svcore
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 00008 This program is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU General Public License as 00010 published by the Free Software Foundation; either version 2 of the 00011 License, or (at your option) any later version. See the file 00012 COPYING included with this distribution for more information. 00013 */ 00014 00015 /* 00016 This is a modified version of a source file from the 00017 Rosegarden MIDI and audio sequencer and notation editor. 00018 This file copyright 2000-2010 Chris Cannam. 00019 */ 00020 00021 #include "StringBits.h" 00022 00023 double 00024 StringBits::stringToDoubleLocaleFree(QString s, bool *ok) 00025 { 00026 int dp = 0; 00027 int sign = 1; 00028 int i = 0; 00029 double result = 0.0; 00030 int len = s.length(); 00031 00032 result = 0.0; 00033 00034 if (ok) *ok = true; 00035 00036 while (i < len && s[i].isSpace()) ++i; 00037 if (i < len && s[i] == '-') sign = -1; 00038 00039 while (i < len) { 00040 00041 QChar c = s[i]; 00042 00043 if (c.isDigit()) { 00044 00045 double d = c.digitValue(); 00046 00047 if (dp > 0) { 00048 for (int p = dp; p > 0; --p) d /= 10.0; 00049 ++dp; 00050 } else { 00051 result *= 10.0; 00052 } 00053 00054 result += d; 00055 00056 } else if (c == '.') { 00057 00058 dp = 1; 00059 00060 } else if (ok) { 00061 *ok = false; 00062 } 00063 00064 ++i; 00065 } 00066 00067 return result * sign; 00068 } 00069 00070 QStringList 00071 StringBits::splitQuoted(QString s, QChar separator) 00072 { 00073 QStringList tokens; 00074 QString tok; 00075 00076 enum { sep, unq, q1, q2 } mode = sep; 00077 00078 for (int i = 0; i < s.length(); ++i) { 00079 00080 QChar c = s[i]; 00081 00082 if (c == '\'') { 00083 switch (mode) { 00084 case sep: mode = q1; break; 00085 case unq: case q2: tok += c; break; 00086 case q1: mode = sep; tokens << tok; tok = ""; break; 00087 } 00088 00089 } else if (c == '"') { 00090 switch (mode) { 00091 case sep: mode = q2; break; 00092 case unq: case q1: tok += c; break; 00093 case q2: mode = sep; tokens << tok; tok = ""; break; 00094 } 00095 00096 } else if (c == separator || (separator == ' ' && c.isSpace())) { 00097 switch (mode) { 00098 case sep: if (separator != ' ') tokens << ""; break; 00099 case unq: mode = sep; tokens << tok; tok = ""; break; 00100 case q1: case q2: tok += c; break; 00101 } 00102 00103 } else if (c == '\\') { 00104 if (++i < s.length()) { 00105 c = s[i]; 00106 switch (mode) { 00107 case sep: mode = unq; tok += c; break; 00108 case unq: case q1: case q2: tok += c; break; 00109 } 00110 } 00111 00112 } else { 00113 switch (mode) { 00114 case sep: mode = unq; tok += c; break; 00115 case unq: case q1: case q2: tok += c; break; 00116 } 00117 } 00118 } 00119 00120 if (tok != "" || mode != sep) tokens << tok; 00121 return tokens; 00122 } 00123 00124 /* 00125 00126 void testSplit() 00127 { 00128 QStringList tests; 00129 tests << "a b c d"; 00130 tests << "a \"b c\" d"; 00131 tests << "a 'b c' d"; 00132 tests << "a \"b c\\\" d\""; 00133 tests << "a 'b c\\' d'"; 00134 tests << "a \"b c' d\""; 00135 tests << "a 'b c\" d'"; 00136 tests << "aa 'bb cc\" dd'"; 00137 tests << "a'a 'bb' \\\"cc\" dd\\\""; 00138 tests << " a'a \\\' 'bb' \' \\\"cc\" ' dd\\\" '"; 00139 00140 for (int j = 0; j < tests.size(); ++j) { 00141 cout << endl; 00142 cout << tests[j] << endl; 00143 cout << "->" << endl << "("; 00144 QStringList l = splitQuoted(tests[j], ' '); 00145 for (int i = 0; i < l.size(); ++i) { 00146 if (i > 0) cout << ";"; 00147 cout << l[i]; 00148 } 00149 cout << ")" << endl; 00150 } 00151 } 00152 00153 */ 00154 00155 /* 00156 Results: 00157 00158 a b c d 00159 -> 00160 (a;b;c;d) 00161 00162 a "b c" d 00163 -> 00164 (a;b c;d) 00165 00166 a 'b c' d 00167 -> 00168 (a;b c;d) 00169 00170 a "b c\" d" 00171 -> 00172 (a;b c" d) 00173 00174 a 'b c\' d' 00175 -> 00176 (a;b c' d) 00177 00178 a "b c' d" 00179 -> 00180 (a;b c' d) 00181 00182 a 'b c" d' 00183 -> 00184 (a;b c" d) 00185 00186 aa 'bb cc" dd' 00187 -> 00188 (aa;bb cc" dd) 00189 00190 a'a 'bb' \"cc" dd\" 00191 -> 00192 (a'a;bb;"cc";dd") 00193 00194 a'a \' 'bb' ' \"cc" ' dd\" ' 00195 -> 00196 (a'a;';bb; "cc" ;dd";) 00197 00198 */ 00199 00200 QStringList 00201 StringBits::split(QString line, QChar separator, bool quoted) 00202 { 00203 if (quoted) { 00204 return splitQuoted(line, separator); 00205 } else { 00206 return line.split(separator, 00207 separator == ' ' ? QString::SkipEmptyParts : 00208 QString::KeepEmptyParts); 00209 } 00210 } 00211