~ubuntu-branches/ubuntu/intrepid/gsmlib/intrepid

« back to all changes in this revision

Viewing changes to gsmlib/gsm_parser.cc

  • Committer: Bazaar Package Importer
  • Author(s): Mikael Hedin
  • Date: 2002-01-24 12:59:07 UTC
  • Revision ID: james.westby@ubuntu.com-20020124125907-b7qkpokx5283jdpu
Tags: upstream-1.8
ImportĀ upstreamĀ versionĀ 1.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// *************************************************************************
 
2
// * GSM TA/ME library
 
3
// *
 
4
// * File:    gsm_parser.cc
 
5
// *
 
6
// * Purpose: Parser to parse MA/TA result strings
 
7
// *
 
8
// * Author:  Peter Hofmann (software@pxh.de)
 
9
// *
 
10
// * Created: 13.5.1999
 
11
// *************************************************************************
 
12
 
 
13
#ifdef HAVE_CONFIG_H
 
14
#include <gsm_config.h>
 
15
#endif
 
16
#include <gsmlib/gsm_parser.h>
 
17
#include <gsmlib/gsm_nls.h>
 
18
#include <ctype.h>
 
19
#include <assert.h>
 
20
#include <strstream>
 
21
 
 
22
using namespace std;
 
23
using namespace gsmlib;
 
24
 
 
25
// Parser members
 
26
 
 
27
int Parser::nextChar(bool skipWhiteSpace)
 
28
{
 
29
  if (skipWhiteSpace)
 
30
    while (_i < _s.length() && isspace(_s[_i])) ++_i;
 
31
 
 
32
  if (_i == _s.length())
 
33
  {
 
34
    _eos = true;
 
35
    return -1;
 
36
  }
 
37
 
 
38
  return _s[_i++];
 
39
}
 
40
    
 
41
bool Parser::checkEmptyParameter(bool allowNoParameter) throw(GsmException)
 
42
{
 
43
  int c = nextChar();
 
44
  if (c == ',' || c == -1)
 
45
    if (allowNoParameter)
 
46
    {
 
47
      putBackChar();
 
48
      return true;
 
49
    }
 
50
    else
 
51
      throwParseException(_("expected parameter"));
 
52
 
 
53
  putBackChar();
 
54
  return false;
 
55
}
 
56
    
 
57
string Parser::parseString2(bool stringWithQuotationMarks)
 
58
  throw(GsmException)
 
59
{
 
60
  int c;
 
61
  string result;
 
62
  if (parseChar('"', true))  // OK, string starts and ends with quotation mark
 
63
    if (stringWithQuotationMarks)
 
64
    {
 
65
      // read till end of line
 
66
      while ((c = nextChar(false)) != -1)
 
67
        result += c;
 
68
      
 
69
      // check for """ at end of line
 
70
      if (result.length() == 0 || result[result.length() - 1]  != '"')
 
71
        throwParseException(_("expected '\"'"));
 
72
      
 
73
      // remove """ at the end
 
74
      result.resize(result.length() - 1);
 
75
    }
 
76
    else
 
77
    {
 
78
      // read till next """
 
79
      while ((c = nextChar(false)) != '"')
 
80
        if (c == -1)
 
81
          throwParseException();
 
82
        else
 
83
          result += c;
 
84
    }
 
85
  else                          // string ends with "," or EOL
 
86
  {
 
87
    c = nextChar(false);
 
88
    while (c != ',' && c != -1)
 
89
    {
 
90
      result += c;
 
91
      c = nextChar(false);
 
92
    }
 
93
    if (c == ',') putBackChar();
 
94
  }
 
95
    
 
96
  return result;
 
97
}
 
98
 
 
99
int Parser::parseInt2() throw(GsmException)
 
100
{
 
101
  string s;
 
102
  int c;
 
103
  int result;
 
104
 
 
105
  while (isdigit(c = nextChar())) s += c;
 
106
 
 
107
  putBackChar();
 
108
  if (s.length() == 0)
 
109
    throwParseException(_("expected number"));
 
110
 
 
111
  istrstream is(s.c_str());
 
112
  is >> result;
 
113
  return result;
 
114
}
 
115
 
 
116
void Parser::throwParseException(string message) throw(GsmException)
 
117
{
 
118
  ostrstream os;
 
119
  if (message.length() == 0)
 
120
    throw GsmException(stringPrintf(_("unexpected end of string '%s'"),
 
121
                                    _s.c_str()), ParserError);
 
122
  else
 
123
    throw GsmException(message +
 
124
                       stringPrintf(_(" (at position %d of string '%s')"), _i,
 
125
                                    _s.c_str()), ParserError);
 
126
}
 
127
 
 
128
Parser::Parser(string s) : _i(0), _s(s), _eos(false)
 
129
{
 
130
}
 
131
 
 
132
bool Parser::parseChar(char c, bool allowNoChar) throw(GsmException)
 
133
{
 
134
  if (nextChar() != c)
 
135
    if (allowNoChar)
 
136
    {
 
137
      putBackChar();
 
138
      return false;
 
139
    }
 
140
    else
 
141
      throwParseException(stringPrintf(_("expected '%c'"), c));
 
142
  return true;
 
143
}
 
144
 
 
145
vector<string> Parser::parseStringList(bool allowNoList)
 
146
  throw(GsmException)
 
147
{
 
148
  // handle case of empty parameter
 
149
  vector<string> result;
 
150
  if (checkEmptyParameter(allowNoList)) return result;
 
151
 
 
152
  parseChar('(');
 
153
  if (nextChar() != ')')
 
154
  {
 
155
    putBackChar();
 
156
    while (1)
 
157
    {
 
158
      result.push_back(parseString());
 
159
      int c = nextChar();
 
160
      if (c == ')')
 
161
      break;
 
162
      if (c == -1)
 
163
        throwParseException();
 
164
      if (c != ',')
 
165
        throwParseException(_("expected ')' or ','"));
 
166
    }
 
167
  }
 
168
  
 
169
  return result;
 
170
}
 
171
 
 
172
vector<bool> Parser::parseIntList(bool allowNoList)
 
173
  throw(GsmException)
 
174
{
 
175
  // handle case of empty parameter
 
176
  bool isRange = false;
 
177
  vector<bool> result;
 
178
  int resultCapacity = 0;
 
179
  unsigned int saveI = _i;
 
180
 
 
181
  if (checkEmptyParameter(allowNoList)) return result;
 
182
 
 
183
  // check for the case of a integer list consisting of only one parameter
 
184
  // some TAs omit the parentheses in this case
 
185
  if (isdigit(nextChar()))
 
186
  {
 
187
    putBackChar();
 
188
    int num = parseInt();
 
189
    result.resize(num + 1, false);
 
190
    result[num] = true;
 
191
    return result;
 
192
  }
 
193
  putBackChar();
 
194
 
 
195
  // run in two passes
 
196
  // pass 0: find capacity needed for result
 
197
  // pass 1: resize result and fill it in
 
198
  for (int pass = 0; pass < 2; ++pass)
 
199
  {
 
200
    if (pass == 1)
 
201
    {
 
202
      _i = saveI;
 
203
      result.resize(resultCapacity + 1, false);
 
204
    }
 
205
 
 
206
    parseChar('(');
 
207
    if (nextChar() != ')')
 
208
    {
 
209
      putBackChar();
 
210
      int lastInt = -1;
 
211
      while (1)
 
212
      {
 
213
        int thisInt = parseInt();
 
214
 
 
215
        if (isRange)
 
216
        {
 
217
          assert(lastInt != -1);
 
218
          if (lastInt <= thisInt)
 
219
            for (int i = lastInt; i < thisInt; ++i)
 
220
            {
 
221
              if (i > resultCapacity)
 
222
                resultCapacity = i;
 
223
              if (pass == 1)
 
224
                result[i] = true;
 
225
            }
 
226
          else
 
227
            for (int i = thisInt; i < lastInt; ++i)
 
228
            {
 
229
              if (i > resultCapacity)
 
230
                resultCapacity = i;
 
231
              if (pass == 1)
 
232
                result[i] = true;
 
233
            }
 
234
          isRange = false;
 
235
        }
 
236
 
 
237
        if (thisInt > resultCapacity)
 
238
          resultCapacity = thisInt;
 
239
        if (pass == 1)
 
240
          result[thisInt] = true;
 
241
        lastInt = thisInt;
 
242
      
 
243
        int c = nextChar();
 
244
        if (c == ')')
 
245
          break;
 
246
 
 
247
        if (c == -1)
 
248
          throwParseException();
 
249
 
 
250
        if (c != ',' && c != '-')
 
251
          throwParseException(_("expected ')', ',' or '-'"));
 
252
 
 
253
        if (c == ',')
 
254
          isRange = false;
 
255
        else                      // is '-'
 
256
          if (isRange)
 
257
            throwParseException(_("range of the form a-b-c not allowed"));
 
258
          else
 
259
            isRange = true;
 
260
      }
 
261
    }
 
262
  }
 
263
  if (isRange)
 
264
    throwParseException(_("range of the form a- no allowed"));
 
265
  return result;
 
266
}
 
267
 
 
268
IntRange Parser::parseRange(bool allowNoRange)
 
269
  throw(GsmException)
 
270
{
 
271
  // handle case of empty parameter
 
272
  IntRange result;
 
273
  if (checkEmptyParameter(allowNoRange)) return result;
 
274
 
 
275
  parseChar('(');
 
276
  result._low = parseInt();
 
277
  parseChar('-');
 
278
  result._high = parseInt();
 
279
  parseChar(')');
 
280
 
 
281
  return result;
 
282
}
 
283
 
 
284
int Parser::parseInt(bool allowNoInt) throw(GsmException)
 
285
{
 
286
  // handle case of empty parameter
 
287
  int result = NOT_SET;
 
288
  if (checkEmptyParameter(allowNoInt)) return result;
 
289
 
 
290
  result = parseInt2();
 
291
 
 
292
  return result;
 
293
}
 
294
 
 
295
string Parser::parseString(bool allowNoString,
 
296
                           bool stringWithQuotationMarks)
 
297
  throw(GsmException)
 
298
{
 
299
  // handle case of empty parameter
 
300
  string result;
 
301
  if (checkEmptyParameter(allowNoString)) return result;
 
302
 
 
303
  result = parseString2(stringWithQuotationMarks);
 
304
 
 
305
  return result;
 
306
}
 
307
 
 
308
bool Parser::parseComma(bool allowNoComma) throw(GsmException)
 
309
{
 
310
  if (nextChar() != ',')
 
311
    if(allowNoComma)
 
312
    {
 
313
      putBackChar();
 
314
      return false;
 
315
    }
 
316
    else
 
317
      throwParseException(_("expected comma"));
 
318
  return true;
 
319
}
 
320
 
 
321
string Parser::parseEol() throw(GsmException)
 
322
{
 
323
  string result;
 
324
  int c;
 
325
  while ((c = nextChar()) != -1) result += c;
 
326
  return result;
 
327
}
 
328
 
 
329
void Parser::checkEol() throw(GsmException)
 
330
{
 
331
  if (nextChar() != -1)
 
332
  {
 
333
    putBackChar();
 
334
    throwParseException(_("expected end of line"));
 
335
  }
 
336
}
 
337
 
 
338
string Parser::getEol()
 
339
{
 
340
  string result;
 
341
  int c;
 
342
  unsigned int saveI = _i;
 
343
  bool saveEos = _eos;
 
344
  while ((c = nextChar()) != -1) result += c;
 
345
  _i = saveI;
 
346
  _eos = saveEos;
 
347
  return result;
 
348
}