~ubuntu-branches/ubuntu/precise/pingus/precise

« back to all changes in this revision

Viewing changes to src/PLFParser.cc

  • Committer: Bazaar Package Importer
  • Author(s): Raphael Goulais
  • Date: 2004-08-09 10:26:00 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20040809102600-lg2q9lfars0q1p42
Tags: 0.6.0-8
Applied patch from Andreas Jochens (Closes: #263992)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//  $Id: PLFParser.cc,v 1.12 2001/06/11 08:45:21 grumbel Exp $
2
 
//
3
 
//  Pingus - A free Lemmings clone
4
 
//  Copyright (C) 1999 Ingo Ruhnke <grumbel@gmx.de>
5
 
//
6
 
//  This program is free software; you can redistribute it and/or
7
 
//  modify it under the terms of the GNU General Public License
8
 
//  as published by the Free Software Foundation; either version 2
9
 
//  of the License, or (at your option) any later version.
10
 
//
11
 
//  This program is distributed in the hope that it will be useful,
12
 
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
//  GNU General Public License for more details.
15
 
//
16
 
//  You should have received a copy of the GNU General Public License
17
 
//  along with this program; if not, write to the Free Software
18
 
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
 
 
20
 
#include <iostream>
21
 
#include <cstdio>
22
 
#include <cstdlib>
23
 
#include <string>
24
 
#include <fstream>
25
 
 
26
 
#include "StringConverter.hh"
27
 
#include "PLFParser.hh"
28
 
#include "PingusError.hh"
29
 
#include "globals.hh"
30
 
 
31
 
using namespace std;
32
 
 
33
 
PLFParserEOF::PLFParserEOF()
34
 
{
35
 
}
36
 
 
37
 
PLFParser::PLFParser()
38
 
{
39
 
}
40
 
 
41
 
// Destroy all data
42
 
PLFParser::~PLFParser()
43
 
{
44
 
}
45
 
 
46
 
void
47
 
PLFParser::init(string filename)
48
 
{
49
 
  // Init local vars
50
 
  last_atom = ' ';
51
 
  lineno = 1;
52
 
 
53
 
  // Start parsing
54
 
  open(filename);
55
 
  parse();
56
 
}
57
 
 
58
 
// Open the file and do some error checking.
59
 
void
60
 
PLFParser::open(string filename)
61
 
{
62
 
  in.open(filename.c_str());
63
 
  eof = false;
64
 
 
65
 
  if (!in) {
66
 
    throw PingusError("Couldn't open: " + filename);
67
 
  }
68
 
  
69
 
  if (verbose > 1)
70
 
    cout << "Successfully opened plf file" << endl;
71
 
}
72
 
 
73
 
// Return the next char from file and check for eof.
74
 
char
75
 
PLFParser::get_char(void)
76
 
{
77
 
  int c;
78
 
 
79
 
  if (eof) {
80
 
    if (verbose > 1) cout << "PLFParser: Result of get_char() will be undefined" << endl;
81
 
    // throw PingusError("");
82
 
  }
83
 
 
84
 
  c = in.get();
85
 
 
86
 
  if (c == EOF) {
87
 
    if (verbose > 1) cout << "PLF::get_char(): Found EOF!" << endl;
88
 
    eof = true;
89
 
    // throw PLFParserEOF();
90
 
  }
91
 
 
92
 
  if (c == '\n')
93
 
    ++lineno;
94
 
 
95
 
  return c;
96
 
}
97
 
 
98
 
// Return the next char from file, remove all comments and spaces before.
99
 
char
100
 
PLFParser::get_raw_atom(void)
101
 
{
102
 
  char c;
103
 
  char temp_c;
104
 
  c = get_char();
105
 
 
106
 
  // Ignoring "//" comments
107
 
  if (c == '/') {
108
 
    char ic;
109
 
    if ((ic = get_char()) == '/') {
110
 
      while(get_char() != '\n'); // Ignoring until EOL
111
 
      return get_atom();
112
 
    } else {
113
 
      in.putback(ic);
114
 
    }
115
 
  }
116
 
 
117
 
  if (c == '/') {
118
 
    if ((c = get_char()) == '*') {
119
 
      while(true) {
120
 
        c = get_char();
121
 
        if (c == '*')
122
 
          if (get_char() == '/')
123
 
            return get_atom();
124
 
      }
125
 
    } else {
126
 
      in.putback(c);
127
 
    }
128
 
  }
129
 
  
130
 
  if (isspace(c)) {
131
 
    temp_c = c;
132
 
    while (isspace(c = get_char()));
133
 
    in.putback(c);
134
 
    if (isspace(last_atom)) 
135
 
      return get_atom();
136
 
    return temp_c;
137
 
  }
138
 
 
139
 
  return c;
140
 
}
141
 
 
142
 
// Return the next atom and keep it.
143
 
char
144
 
PLFParser::get_atom(void)
145
 
{
146
 
  last_atom = get_raw_atom();
147
 
  
148
 
  return last_atom;
149
 
}
150
 
 
151
 
string
152
 
PLFParser::get_groupname(void)
153
 
{
154
 
  char atom;
155
 
  string ret_val;
156
 
  
157
 
  jump();
158
 
 
159
 
  while((isalpha(atom = get_atom()) || atom == '_')) 
160
 
    {
161
 
      ret_val += atom;
162
 
    }
163
 
 
164
 
  if (eof) 
165
 
    return ""; 
166
 
      
167
 
  if (ret_val.empty())
168
 
    syntax_error(string("Invalid group name: Found char: '") + atom + "'");
169
 
 
170
 
  return ret_val;
171
 
}
172
 
 
173
 
// Return the name of the value identiver.
174
 
string
175
 
PLFParser::get_valueid(void)
176
 
{
177
 
  string ret_val;
178
 
  char   atom;
179
 
  
180
 
  jump();
181
 
 
182
 
  while(true) {
183
 
    atom = get_atom();
184
 
    
185
 
    if (atom == '}' && ret_val.empty()) {
186
 
      return "}";
187
 
    }
188
 
 
189
 
    if (isalpha(atom) || atom == '_') {
190
 
      ret_val += atom;
191
 
    } else if (isspace(atom)) {
192
 
      return ret_val;
193
 
    } else if (atom == '=') {
194
 
      in.putback(atom);
195
 
      return ret_val;
196
 
    } else {
197
 
      syntax_error(string("Unexpected char: '") + atom + "'");
198
 
    }
199
 
  }  
200
 
  
201
 
  return ret_val;
202
 
}
203
 
 
204
 
string
205
 
PLFParser::get_value(void)
206
 
{
207
 
  string ret_val;
208
 
  char   atom;
209
 
 
210
 
  jump();
211
 
 
212
 
  while(true) {
213
 
    atom = get_atom();
214
 
 
215
 
    if (atom == '"' && ret_val == "") {
216
 
      while((atom = get_char()) != '"') {
217
 
        ret_val += atom;
218
 
      }
219
 
      return ret_val;
220
 
    }
221
 
 
222
 
    if (atom == ';') {
223
 
      in.putback(atom);
224
 
      return ret_val;
225
 
    }
226
 
   
227
 
    if (!isalnum(atom) && atom != '-' && atom != '_' && atom != '.')
228
 
      {
229
 
        if (isspace(atom)){
230
 
          return ret_val;
231
 
        } else {
232
 
          syntax_error(string("Unexpected char '") + atom + "'");
233
 
        }
234
 
      }
235
 
    
236
 
    ret_val += atom;
237
 
  }
238
 
  
239
 
  return ret_val;
240
 
}
241
 
 
242
 
string
243
 
PLFParser::get_cast(void)
244
 
{
245
 
  string ret_val;
246
 
  char   atom;
247
 
  jump();
248
 
  
249
 
  atom = get_atom();
250
 
 
251
 
  if (atom != '(') {
252
 
    in.putback(atom);
253
 
    return ret_val;
254
 
  } else {
255
 
    while(true) {
256
 
      atom = get_atom();
257
 
      if (atom == ')')
258
 
        break;
259
 
      ret_val += atom;
260
 
    }
261
 
  }
262
 
  return ret_val;
263
 
}
264
 
 
265
 
// Jumps to the position of the next token after 'a', no other char's
266
 
// then spaces are allowed before 'a'.
267
 
void
268
 
PLFParser::jump_after(char c)
269
 
{
270
 
  char atom;
271
 
  
272
 
  jump();
273
 
 
274
 
  atom = get_atom();
275
 
  if (isspace(atom) || atom == c) {
276
 
    if (atom == c) {
277
 
      return;
278
 
    } else {
279
 
      atom = get_atom();
280
 
      if (atom == c)
281
 
        return;
282
 
    }
283
 
  } 
284
 
  syntax_error(string("jump_after(): Expected '") + c + "', got '" + atom + "'" );
285
 
}
286
 
 
287
 
void
288
 
PLFParser::jump(void)
289
 
{
290
 
  char atom;
291
 
  atom = get_atom();
292
 
 
293
 
  if (isspace(atom)) {
294
 
    return;
295
 
  } else {
296
 
    in.putback(atom);
297
 
  }
298
 
}
299
 
 
300
 
// Print a error message with lineno and filename.
301
 
void
302
 
PLFParser::syntax_error(string error = "")
303
 
{
304
 
  string error_str;
305
 
 
306
 
  error_str = "PLF: Syntax Error at line " + to_string (lineno);
307
 
 
308
 
  if (error != "")
309
 
    error_str += ":PLF:" + error + "\n";
310
 
 
311
 
  throw PingusError(error_str);
312
 
}
313
 
 
314
 
// Parse the file and fill all structs with the values.
315
 
void
316
 
PLFParser::parse(void)
317
 
{
318
 
  string groupname;
319
 
  string valueid;
320
 
  string cast;
321
 
  string value;
322
 
 
323
 
  while(!eof) 
324
 
    {
325
 
      groupname = get_groupname();
326
 
 
327
 
      if (eof) break;   
328
 
 
329
 
      set_group_start(groupname);
330
 
      jump_after('{');
331
 
 
332
 
      while(true) 
333
 
        {
334
 
          valueid = get_valueid();
335
 
 
336
 
          if (valueid == "}")
337
 
            break;
338
 
          
339
 
          jump_after('=');
340
 
          cast    = get_cast();
341
 
          value   = get_value();
342
 
          jump_after(';');
343
 
          
344
 
          if (verbose > 2) 
345
 
            {
346
 
              cout << "ValueID: " << valueid << endl;
347
 
              cout << "Cast: " << cast << endl;
348
 
              cout << "Value: " << value << endl;
349
 
            }
350
 
          set_value(valueid, cast, value);
351
 
        }
352
 
      set_group_end();
353
 
      jump();
354
 
    }
355
 
  
356
 
  /*  catch(PLFParserEOF a) {
357
 
    if (verbose > 1) cout << "PLF: Catched EOF" << endl;
358
 
    }*/
359
 
}
360
 
 
361
 
/* EOF */