annotate base/StringBits.cpp @ 1184:e5a1d815f331 3.0-integration

Merge from the default branch
author Chris Cannam
date Thu, 21 Apr 2016 15:29:30 +0100
parents eecf544bed92
children 48e9f538e6e9
rev   line source
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@1022 23 #include "Debug.h"
Chris@1022 24
Chris@1022 25 using namespace std;
Chris@1022 26
Chris@629 27 double
Chris@629 28 StringBits::stringToDoubleLocaleFree(QString s, bool *ok)
Chris@629 29 {
Chris@629 30 int dp = 0;
Chris@629 31 int sign = 1;
Chris@629 32 int i = 0;
Chris@629 33 double result = 0.0;
Chris@629 34 int len = s.length();
Chris@629 35
Chris@629 36 result = 0.0;
Chris@629 37
Chris@629 38 if (ok) *ok = true;
Chris@629 39
Chris@629 40 while (i < len && s[i].isSpace()) ++i;
Chris@629 41 if (i < len && s[i] == '-') sign = -1;
Chris@629 42
Chris@629 43 while (i < len) {
Chris@629 44
Chris@629 45 QChar c = s[i];
Chris@629 46
Chris@629 47 if (c.isDigit()) {
Chris@629 48
Chris@629 49 double d = c.digitValue();
Chris@629 50
Chris@629 51 if (dp > 0) {
Chris@629 52 for (int p = dp; p > 0; --p) d /= 10.0;
Chris@629 53 ++dp;
Chris@629 54 } else {
Chris@629 55 result *= 10.0;
Chris@629 56 }
Chris@629 57
Chris@629 58 result += d;
Chris@629 59
Chris@629 60 } else if (c == '.') {
Chris@629 61
Chris@629 62 dp = 1;
Chris@629 63
Chris@629 64 } else if (ok) {
Chris@629 65 *ok = false;
Chris@629 66 }
Chris@629 67
Chris@629 68 ++i;
Chris@629 69 }
Chris@629 70
Chris@629 71 return result * sign;
Chris@629 72 }
Chris@629 73
Chris@629 74 QStringList
Chris@629 75 StringBits::splitQuoted(QString s, QChar separator)
Chris@629 76 {
Chris@629 77 QStringList tokens;
Chris@629 78 QString tok;
Chris@629 79
Chris@1022 80 // sep -> just seen a field separator (or start of line)
Chris@1022 81 // unq -> in an unquoted field
Chris@1022 82 // q1 -> in a single-quoted field
Chris@1022 83 // q2 -> in a double-quoted field
Chris@1022 84
Chris@629 85 enum { sep, unq, q1, q2 } mode = sep;
Chris@629 86
Chris@629 87 for (int i = 0; i < s.length(); ++i) {
Chris@629 88
Chris@629 89 QChar c = s[i];
Chris@629 90
Chris@629 91 if (c == '\'') {
Chris@629 92 switch (mode) {
Chris@629 93 case sep: mode = q1; break;
Chris@629 94 case unq: case q2: tok += c; break;
Chris@1019 95 case q1: mode = unq; break;
Chris@629 96 }
Chris@629 97
Chris@629 98 } else if (c == '"') {
Chris@629 99 switch (mode) {
Chris@629 100 case sep: mode = q2; break;
Chris@629 101 case unq: case q1: tok += c; break;
Chris@1019 102 case q2: mode = unq; break;
Chris@629 103 }
Chris@629 104
Chris@629 105 } else if (c == separator || (separator == ' ' && c.isSpace())) {
Chris@629 106 switch (mode) {
Chris@629 107 case sep: if (separator != ' ') tokens << ""; break;
Chris@629 108 case unq: mode = sep; tokens << tok; tok = ""; break;
Chris@629 109 case q1: case q2: tok += c; break;
Chris@629 110 }
Chris@629 111
Chris@629 112 } else if (c == '\\') {
Chris@629 113 if (++i < s.length()) {
Chris@629 114 c = s[i];
Chris@629 115 switch (mode) {
Chris@629 116 case sep: mode = unq; tok += c; break;
Chris@928 117 case unq: case q1: case q2: tok += c; break;
Chris@629 118 }
Chris@629 119 }
Chris@629 120
Chris@629 121 } else {
Chris@629 122 switch (mode) {
Chris@629 123 case sep: mode = unq; tok += c; break;
Chris@928 124 case unq: case q1: case q2: tok += c; break;
Chris@629 125 }
Chris@629 126 }
Chris@629 127 }
Chris@629 128
Chris@1022 129 if (tok != "" || mode != sep) {
Chris@1022 130 if (mode == q1) {
Chris@1022 131 tokens << ("'" + tok); // turns out it wasn't quoted after all
Chris@1022 132 } else if (mode == q2) {
Chris@1022 133 tokens << ("\"" + tok);
Chris@1022 134 } else {
Chris@1022 135 tokens << tok;
Chris@1022 136 }
Chris@1022 137 }
Chris@1022 138
Chris@629 139 return tokens;
Chris@629 140 }
Chris@629 141
Chris@629 142 QStringList
Chris@629 143 StringBits::split(QString line, QChar separator, bool quoted)
Chris@629 144 {
Chris@629 145 if (quoted) {
Chris@629 146 return splitQuoted(line, separator);
Chris@629 147 } else {
Chris@629 148 return line.split(separator,
Chris@629 149 separator == ' ' ? QString::SkipEmptyParts :
Chris@629 150 QString::KeepEmptyParts);
Chris@629 151 }
Chris@629 152 }
Chris@629 153