Chris@629: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@629: Chris@629: /* Chris@629: Sonic Visualiser Chris@629: An audio file viewer and annotation editor. Chris@629: Centre for Digital Music, Queen Mary, University of London. Chris@629: Chris@629: This program is free software; you can redistribute it and/or Chris@629: modify it under the terms of the GNU General Public License as Chris@629: published by the Free Software Foundation; either version 2 of the Chris@629: License, or (at your option) any later version. See the file Chris@629: COPYING included with this distribution for more information. Chris@629: */ Chris@629: Chris@629: /* Chris@629: This is a modified version of a source file from the Chris@629: Rosegarden MIDI and audio sequencer and notation editor. Chris@629: This file copyright 2000-2010 Chris Cannam. Chris@629: */ Chris@629: Chris@629: #include "StringBits.h" Chris@629: Chris@1022: #include "Debug.h" Chris@1022: Chris@1022: using namespace std; Chris@1022: Chris@629: double Chris@629: StringBits::stringToDoubleLocaleFree(QString s, bool *ok) Chris@629: { Chris@629: int dp = 0; Chris@629: int sign = 1; Chris@629: int i = 0; Chris@629: double result = 0.0; Chris@629: int len = s.length(); Chris@629: Chris@629: result = 0.0; Chris@629: Chris@629: if (ok) *ok = true; Chris@629: Chris@629: while (i < len && s[i].isSpace()) ++i; Chris@629: if (i < len && s[i] == '-') sign = -1; Chris@629: Chris@629: while (i < len) { Chris@629: Chris@1429: QChar c = s[i]; Chris@629: Chris@629: if (c.isDigit()) { Chris@629: Chris@629: double d = c.digitValue(); Chris@629: Chris@629: if (dp > 0) { Chris@629: for (int p = dp; p > 0; --p) d /= 10.0; Chris@629: ++dp; Chris@629: } else { Chris@629: result *= 10.0; Chris@629: } Chris@629: Chris@629: result += d; Chris@629: Chris@629: } else if (c == '.') { Chris@629: Chris@629: dp = 1; Chris@629: Chris@629: } else if (ok) { Chris@629: *ok = false; Chris@629: } Chris@629: Chris@629: ++i; Chris@629: } Chris@629: Chris@629: return result * sign; Chris@629: } Chris@629: Chris@629: QStringList Chris@629: StringBits::splitQuoted(QString s, QChar separator) Chris@629: { Chris@629: QStringList tokens; Chris@629: QString tok; Chris@629: Chris@1022: // sep -> just seen a field separator (or start of line) Chris@1022: // unq -> in an unquoted field Chris@1022: // q1 -> in a single-quoted field Chris@1022: // q2 -> in a double-quoted field Chris@1022: Chris@629: enum { sep, unq, q1, q2 } mode = sep; Chris@629: Chris@629: for (int i = 0; i < s.length(); ++i) { Chris@1429: Chris@1429: QChar c = s[i]; Chris@629: Chris@1429: if (c == '\'') { Chris@1429: switch (mode) { Chris@1429: case sep: mode = q1; break; Chris@1429: case unq: case q2: tok += c; break; Chris@1429: case q1: mode = unq; break; Chris@1429: } Chris@629: Chris@1429: } else if (c == '"') { Chris@1429: switch (mode) { Chris@1429: case sep: mode = q2; break; Chris@1429: case unq: case q1: tok += c; break; Chris@1429: case q2: mode = unq; break; Chris@1429: } Chris@629: Chris@1429: } else if (c == separator || (separator == ' ' && c.isSpace())) { Chris@1429: switch (mode) { Chris@1429: case sep: if (separator != ' ') tokens << ""; break; Chris@1429: case unq: mode = sep; tokens << tok; tok = ""; break; Chris@1429: case q1: case q2: tok += c; break; Chris@1429: } Chris@629: Chris@1429: } else if (c == '\\') { Chris@1429: if (++i < s.length()) { Chris@1429: c = s[i]; Chris@1429: switch (mode) { Chris@1429: case sep: mode = unq; tok += c; break; Chris@928: case unq: case q1: case q2: tok += c; break; Chris@1429: } Chris@1429: } Chris@629: Chris@1429: } else { Chris@1429: switch (mode) { Chris@1429: case sep: mode = unq; tok += c; break; Chris@928: case unq: case q1: case q2: tok += c; break; Chris@1429: } Chris@1429: } Chris@629: } Chris@629: Chris@1022: if (tok != "" || mode != sep) { Chris@1022: if (mode == q1) { Chris@1022: tokens << ("'" + tok); // turns out it wasn't quoted after all Chris@1022: } else if (mode == q2) { Chris@1022: tokens << ("\"" + tok); Chris@1022: } else { Chris@1022: tokens << tok; Chris@1022: } Chris@1022: } Chris@1022: Chris@629: return tokens; Chris@629: } Chris@629: Chris@629: QStringList Chris@629: StringBits::split(QString line, QChar separator, bool quoted) Chris@629: { Chris@629: if (quoted) { Chris@629: return splitQuoted(line, separator); Chris@629: } else { Chris@629: return line.split(separator, Chris@629: separator == ' ' ? QString::SkipEmptyParts : Chris@629: QString::KeepEmptyParts); Chris@629: } Chris@629: } Chris@629: