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