Chris@629
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@629
|
2
|
Chris@629
|
3 /*
|
Chris@629
|
4 Sonic Visualiser
|
Chris@629
|
5 An audio file viewer and annotation editor.
|
Chris@629
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@629
|
7
|
Chris@629
|
8 This program is free software; you can redistribute it and/or
|
Chris@629
|
9 modify it under the terms of the GNU General Public License as
|
Chris@629
|
10 published by the Free Software Foundation; either version 2 of the
|
Chris@629
|
11 License, or (at your option) any later version. See the file
|
Chris@629
|
12 COPYING included with this distribution for more information.
|
Chris@629
|
13 */
|
Chris@629
|
14
|
Chris@629
|
15 /*
|
Chris@629
|
16 This is a modified version of a source file from the
|
Chris@629
|
17 Rosegarden MIDI and audio sequencer and notation editor.
|
Chris@629
|
18 This file copyright 2000-2010 Chris Cannam.
|
Chris@629
|
19 */
|
Chris@629
|
20
|
Chris@629
|
21 #include "StringBits.h"
|
Chris@629
|
22
|
Chris@629
|
23 double
|
Chris@629
|
24 StringBits::stringToDoubleLocaleFree(QString s, bool *ok)
|
Chris@629
|
25 {
|
Chris@629
|
26 int dp = 0;
|
Chris@629
|
27 int sign = 1;
|
Chris@629
|
28 int i = 0;
|
Chris@629
|
29 double result = 0.0;
|
Chris@629
|
30 int len = s.length();
|
Chris@629
|
31
|
Chris@629
|
32 result = 0.0;
|
Chris@629
|
33
|
Chris@629
|
34 if (ok) *ok = true;
|
Chris@629
|
35
|
Chris@629
|
36 while (i < len && s[i].isSpace()) ++i;
|
Chris@629
|
37 if (i < len && s[i] == '-') sign = -1;
|
Chris@629
|
38
|
Chris@629
|
39 while (i < len) {
|
Chris@629
|
40
|
Chris@629
|
41 QChar c = s[i];
|
Chris@629
|
42
|
Chris@629
|
43 if (c.isDigit()) {
|
Chris@629
|
44
|
Chris@629
|
45 double d = c.digitValue();
|
Chris@629
|
46
|
Chris@629
|
47 if (dp > 0) {
|
Chris@629
|
48 for (int p = dp; p > 0; --p) d /= 10.0;
|
Chris@629
|
49 ++dp;
|
Chris@629
|
50 } else {
|
Chris@629
|
51 result *= 10.0;
|
Chris@629
|
52 }
|
Chris@629
|
53
|
Chris@629
|
54 result += d;
|
Chris@629
|
55
|
Chris@629
|
56 } else if (c == '.') {
|
Chris@629
|
57
|
Chris@629
|
58 dp = 1;
|
Chris@629
|
59
|
Chris@629
|
60 } else if (ok) {
|
Chris@629
|
61 *ok = false;
|
Chris@629
|
62 }
|
Chris@629
|
63
|
Chris@629
|
64 ++i;
|
Chris@629
|
65 }
|
Chris@629
|
66
|
Chris@629
|
67 return result * sign;
|
Chris@629
|
68 }
|
Chris@629
|
69
|
Chris@629
|
70 QStringList
|
Chris@629
|
71 StringBits::splitQuoted(QString s, QChar separator)
|
Chris@629
|
72 {
|
Chris@629
|
73 QStringList tokens;
|
Chris@629
|
74 QString tok;
|
Chris@629
|
75
|
Chris@629
|
76 enum { sep, unq, q1, q2 } mode = sep;
|
Chris@629
|
77
|
Chris@629
|
78 for (int i = 0; i < s.length(); ++i) {
|
Chris@629
|
79
|
Chris@629
|
80 QChar c = s[i];
|
Chris@629
|
81
|
Chris@629
|
82 if (c == '\'') {
|
Chris@629
|
83 switch (mode) {
|
Chris@629
|
84 case sep: mode = q1; break;
|
Chris@629
|
85 case unq: case q2: tok += c; break;
|
Chris@629
|
86 case q1: mode = sep; tokens << tok; tok = ""; break;
|
Chris@629
|
87 }
|
Chris@629
|
88
|
Chris@629
|
89 } else if (c == '"') {
|
Chris@629
|
90 switch (mode) {
|
Chris@629
|
91 case sep: mode = q2; break;
|
Chris@629
|
92 case unq: case q1: tok += c; break;
|
Chris@629
|
93 case q2: mode = sep; tokens << tok; tok = ""; break;
|
Chris@629
|
94 }
|
Chris@629
|
95
|
Chris@629
|
96 } else if (c == separator || (separator == ' ' && c.isSpace())) {
|
Chris@629
|
97 switch (mode) {
|
Chris@629
|
98 case sep: if (separator != ' ') tokens << ""; break;
|
Chris@629
|
99 case unq: mode = sep; tokens << tok; tok = ""; break;
|
Chris@629
|
100 case q1: case q2: tok += c; break;
|
Chris@629
|
101 }
|
Chris@629
|
102
|
Chris@629
|
103 } else if (c == '\\') {
|
Chris@629
|
104 if (++i < s.length()) {
|
Chris@629
|
105 c = s[i];
|
Chris@629
|
106 switch (mode) {
|
Chris@629
|
107 case sep: mode = unq; tok += c; break;
|
Chris@928
|
108 case unq: case q1: case q2: tok += c; break;
|
Chris@629
|
109 }
|
Chris@629
|
110 }
|
Chris@629
|
111
|
Chris@629
|
112 } else {
|
Chris@629
|
113 switch (mode) {
|
Chris@629
|
114 case sep: mode = unq; tok += c; break;
|
Chris@928
|
115 case unq: case q1: case q2: tok += c; break;
|
Chris@629
|
116 }
|
Chris@629
|
117 }
|
Chris@629
|
118 }
|
Chris@629
|
119
|
Chris@629
|
120 if (tok != "" || mode != sep) tokens << tok;
|
Chris@629
|
121 return tokens;
|
Chris@629
|
122 }
|
Chris@629
|
123
|
Chris@629
|
124 /*
|
Chris@629
|
125
|
Chris@629
|
126 void testSplit()
|
Chris@629
|
127 {
|
Chris@629
|
128 QStringList tests;
|
Chris@629
|
129 tests << "a b c d";
|
Chris@629
|
130 tests << "a \"b c\" d";
|
Chris@629
|
131 tests << "a 'b c' d";
|
Chris@629
|
132 tests << "a \"b c\\\" d\"";
|
Chris@629
|
133 tests << "a 'b c\\' d'";
|
Chris@629
|
134 tests << "a \"b c' d\"";
|
Chris@629
|
135 tests << "a 'b c\" d'";
|
Chris@629
|
136 tests << "aa 'bb cc\" dd'";
|
Chris@629
|
137 tests << "a'a 'bb' \\\"cc\" dd\\\"";
|
Chris@629
|
138 tests << " a'a \\\' 'bb' \' \\\"cc\" ' dd\\\" '";
|
Chris@629
|
139
|
Chris@629
|
140 for (int j = 0; j < tests.size(); ++j) {
|
Chris@629
|
141 cout << endl;
|
Chris@686
|
142 cout << tests[j] << endl;
|
Chris@629
|
143 cout << "->" << endl << "(";
|
Chris@629
|
144 QStringList l = splitQuoted(tests[j], ' ');
|
Chris@629
|
145 for (int i = 0; i < l.size(); ++i) {
|
Chris@629
|
146 if (i > 0) cout << ";";
|
Chris@844
|
147 cout << l[i];
|
Chris@629
|
148 }
|
Chris@629
|
149 cout << ")" << endl;
|
Chris@629
|
150 }
|
Chris@629
|
151 }
|
Chris@629
|
152
|
Chris@629
|
153 */
|
Chris@629
|
154
|
Chris@629
|
155 /*
|
Chris@629
|
156 Results:
|
Chris@629
|
157
|
Chris@629
|
158 a b c d
|
Chris@629
|
159 ->
|
Chris@629
|
160 (a;b;c;d)
|
Chris@629
|
161
|
Chris@629
|
162 a "b c" d
|
Chris@629
|
163 ->
|
Chris@629
|
164 (a;b c;d)
|
Chris@629
|
165
|
Chris@629
|
166 a 'b c' d
|
Chris@629
|
167 ->
|
Chris@629
|
168 (a;b c;d)
|
Chris@629
|
169
|
Chris@629
|
170 a "b c\" d"
|
Chris@629
|
171 ->
|
Chris@629
|
172 (a;b c" d)
|
Chris@629
|
173
|
Chris@629
|
174 a 'b c\' d'
|
Chris@629
|
175 ->
|
Chris@629
|
176 (a;b c' d)
|
Chris@629
|
177
|
Chris@629
|
178 a "b c' d"
|
Chris@629
|
179 ->
|
Chris@629
|
180 (a;b c' d)
|
Chris@629
|
181
|
Chris@629
|
182 a 'b c" d'
|
Chris@629
|
183 ->
|
Chris@629
|
184 (a;b c" d)
|
Chris@629
|
185
|
Chris@629
|
186 aa 'bb cc" dd'
|
Chris@629
|
187 ->
|
Chris@629
|
188 (aa;bb cc" dd)
|
Chris@629
|
189
|
Chris@629
|
190 a'a 'bb' \"cc" dd\"
|
Chris@629
|
191 ->
|
Chris@629
|
192 (a'a;bb;"cc";dd")
|
Chris@629
|
193
|
Chris@629
|
194 a'a \' 'bb' ' \"cc" ' dd\" '
|
Chris@629
|
195 ->
|
Chris@629
|
196 (a'a;';bb; "cc" ;dd";)
|
Chris@629
|
197
|
Chris@629
|
198 */
|
Chris@629
|
199
|
Chris@629
|
200 QStringList
|
Chris@629
|
201 StringBits::split(QString line, QChar separator, bool quoted)
|
Chris@629
|
202 {
|
Chris@629
|
203 if (quoted) {
|
Chris@629
|
204 return splitQuoted(line, separator);
|
Chris@629
|
205 } else {
|
Chris@629
|
206 return line.split(separator,
|
Chris@629
|
207 separator == ' ' ? QString::SkipEmptyParts :
|
Chris@629
|
208 QString::KeepEmptyParts);
|
Chris@629
|
209 }
|
Chris@629
|
210 }
|
Chris@629
|
211
|