48 { |
48 { |
49 } |
49 } |
50 |
50 |
51 /*****************************************************************************/ |
51 /*****************************************************************************/ |
52 |
52 |
53 NumberListParser::NumberList NumberListParser::parse(const char *data) |
53 NumberListParser::List NumberListParser::parse(const char *data) |
54 { |
54 { |
55 NumberList ret; |
55 List ret; |
56 unsigned int i = 0, size = strlen(data), firstNum = 0U, secondNum = 0U; |
56 unsigned int i = 0, size = strlen(data), firstNum = 0U, secondNum = 0U; |
57 typedef enum { |
57 typedef enum { |
58 SectionStart, |
58 SectionStart, |
59 FirstNumber, |
59 FirstNumber, |
60 Range, |
60 Range, |
106 } |
106 } |
107 break; |
107 break; |
108 |
108 |
109 case Range: |
109 case Range: |
110 if (i >= size) { |
110 if (i >= size) { |
111 secondNum = maximum(); |
111 int max = maximum(); |
112 NumberList r = range(firstNum, secondNum); |
112 // only increasing ranges if second number omitted |
113 ret.splice(ret.end(), r); |
113 if (max >= 0 && firstNum <= (unsigned int) max) { |
|
114 List r = range(firstNum, max); |
|
115 ret.splice(ret.end(), r); |
|
116 } |
114 state = Finished; |
117 state = Finished; |
115 } else if (isNumeric(data[i])) { |
118 } else if (isNumeric(data[i])) { |
116 secondNum = parseNumber(data, &i, size); |
119 secondNum = parseNumber(data, &i, size); |
117 state = SecondNumber; |
120 state = SecondNumber; |
118 } else if (data[i] == ',') { |
121 } else if (data[i] == ',') { |
119 i++; |
122 int max = maximum(); |
120 secondNum = maximum(); |
123 i++; |
121 NumberList r = range(firstNum, secondNum); |
124 if (max >= 0) { |
|
125 List r = range(firstNum, max); |
|
126 ret.splice(ret.end(), r); |
|
127 } |
|
128 state = SectionStart; |
|
129 } else { |
|
130 stringstream err; |
|
131 err << "Invalid character " << data[i] |
|
132 << " at position " << i << "in state " |
|
133 << state << "." << endl; |
|
134 throw runtime_error(err.str()); |
|
135 } |
|
136 break; |
|
137 |
|
138 case SecondNumber: |
|
139 if (i >= size) { |
|
140 List r = range(firstNum, secondNum); |
|
141 ret.splice(ret.end(), r); |
|
142 state = Finished; |
|
143 } else if (data[i] == ',') { |
|
144 i++; |
|
145 List r = range(firstNum, secondNum); |
122 ret.splice(ret.end(), r); |
146 ret.splice(ret.end(), r); |
123 state = SectionStart; |
147 state = SectionStart; |
124 } else { |
148 } else { |
125 stringstream err; |
149 stringstream err; |
126 err << "Invalid character " << data[i] |
150 err << "Invalid character " << data[i] |
128 << state << "." << endl; |
152 << state << "." << endl; |
129 throw runtime_error(err.str()); |
153 throw runtime_error(err.str()); |
130 } |
154 } |
131 break; |
155 break; |
132 |
156 |
133 case SecondNumber: |
|
134 if (i >= size) { |
|
135 NumberList r = range(firstNum, secondNum); |
|
136 ret.splice(ret.end(), r); |
|
137 state = Finished; |
|
138 } else if (data[i] == ',') { |
|
139 i++; |
|
140 NumberList r = range(firstNum, secondNum); |
|
141 ret.splice(ret.end(), r); |
|
142 state = SectionStart; |
|
143 } else { |
|
144 stringstream err; |
|
145 err << "Invalid character " << data[i] |
|
146 << " at position " << i << "in state " |
|
147 << state << "." << endl; |
|
148 throw runtime_error(err.str()); |
|
149 } |
|
150 break; |
|
151 |
|
152 default: |
157 default: |
153 { |
158 { |
154 stringstream err; |
159 stringstream err; |
155 err << "Invalid state " << state << "."; |
160 err << "Invalid state " << state << "."; |
156 throw runtime_error(err.str()); |
161 throw runtime_error(err.str()); |