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

« back to all changes in this revision

Viewing changes to src/config.cxx

  • 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: config.cxx,v 1.13 2003/04/10 18:28:30 grumbel Exp $
 
2
//
 
3
//  Pingus - A free Lemmings clone
 
4
//  Copyright (C) 2000 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 <stdio.h>
 
21
#include <iostream>
 
22
 
 
23
#include "globals.hxx"
 
24
#include "pingus_error.hxx"
 
25
#include "config.hxx"
 
26
 
 
27
#include "cheat.hxx"
 
28
#include "my_gettext.hxx"
 
29
 
 
30
struct ConfigParserEOF {};
 
31
 
 
32
// Create a PLF object and start parsing the given file
 
33
ConfigParser::ConfigParser()
 
34
{
 
35
}
 
36
 
 
37
// Destroy all data
 
38
ConfigParser::~ConfigParser()
 
39
{
 
40
}
 
41
 
 
42
void
 
43
ConfigParser::init(std::string filename)
 
44
{
 
45
  // Init local vars
 
46
  last_atom = ' ';
 
47
  lineno = 1;
 
48
 
 
49
  try {
 
50
    // Start parsing
 
51
    open(filename);
 
52
    parse();
 
53
  }
 
54
 
 
55
  catch (PingusError& err) {
 
56
    std::cout << err.get_message () << std::endl;
 
57
  }
 
58
}
 
59
 
 
60
// Open the file and do some error checking.
 
61
void
 
62
ConfigParser::open(std::string filename)
 
63
{
 
64
  in.open(filename.c_str());
 
65
  eof = false;
 
66
 
 
67
  if (!in) 
 
68
    PingusError::raise(_("Couldn't open: ") + filename);
 
69
    
 
70
  if (verbose > 1)
 
71
    std::cout << "Successfully opened plf file." << std::endl;
 
72
}
 
73
 
 
74
// Return the next char from file and check for eof.
 
75
char
 
76
ConfigParser::get_char(void)
 
77
{
 
78
  int c;
 
79
 
 
80
  if (eof) {
 
81
    if (verbose > 1) std::cout << "ConfigParser: Result of get_char() will be undefined" << std::endl;
 
82
    PingusError::raise("");
 
83
  }
 
84
 
 
85
  c = in.get();
 
86
 
 
87
  if (c == EOF) {
 
88
    if (verbose > 1) std::cout << "PLF::get_char(): Found EOF!" << std::endl;
 
89
    eof = true;
 
90
    throw ConfigParserEOF();
 
91
  }
 
92
 
 
93
  if (c == '\n')
 
94
    ++lineno;
 
95
 
 
96
  return c;
 
97
}
 
98
 
 
99
// Return the next char from file, remove all comments and spaces before.
 
100
char
 
101
ConfigParser::get_raw_atom(void)
 
102
{
 
103
  char c;
 
104
  char temp_c;
 
105
  c = get_char();
 
106
 
 
107
  if (c == '#')
 
108
    {
 
109
      while(get_char() != '\n'); // Ignoring until EOL
 
110
 
 
111
      if (eof)
 
112
        return ' ';
 
113
      
 
114
      return get_atom();
 
115
    }
 
116
 
 
117
  if (isspace(c)) 
 
118
    {
 
119
      temp_c = c;
 
120
      while (isspace(c = get_char()));
 
121
      in.putback(c);
 
122
      if (isspace(last_atom)) 
 
123
        return get_atom();
 
124
      return temp_c;
 
125
    }
 
126
 
 
127
  return c;
 
128
}
 
129
 
 
130
// Return the next atom and keep it.
 
131
char
 
132
ConfigParser::get_atom(void)
 
133
{
 
134
  last_atom = get_raw_atom();
 
135
  
 
136
  return last_atom;
 
137
}
 
138
 
 
139
// Return the name of the value identiver.
 
140
std::string
 
141
ConfigParser::get_valueid(void)
 
142
{
 
143
  std::string ret_val;
 
144
  char   atom;
 
145
  
 
146
  jump();
 
147
 
 
148
  while(true) 
 
149
    {
 
150
      atom = get_atom();
 
151
      
 
152
      if (isgraph(atom) && atom != '=')
 
153
        {
 
154
          ret_val += atom;
 
155
        } 
 
156
      else if (isspace(atom)) 
 
157
        {
 
158
          return ret_val;
 
159
        }
 
160
      else if (atom == '=') 
 
161
        {
 
162
          in.putback(atom);
 
163
          return ret_val;
 
164
        }
 
165
      else 
 
166
        {
 
167
          syntax_error(std::string(_("Unexpected char: '")) + atom + "'");
 
168
        }
 
169
    } 
 
170
  
 
171
  return ret_val;
 
172
}
 
173
 
 
174
std::string
 
175
ConfigParser::get_value(void)
 
176
{
 
177
  std::string ret_val;
 
178
  char   atom;
 
179
 
 
180
  jump();
 
181
 
 
182
  while(true) {
 
183
    atom = get_atom();
 
184
 
 
185
    if (atom == '"' && ret_val == "") {
 
186
      while((atom = get_char()) != '"') {
 
187
        ret_val += atom;
 
188
      }
 
189
      return ret_val;
 
190
    }
 
191
 
 
192
    if (atom == ';') {
 
193
      in.putback(atom);
 
194
      return ret_val;
 
195
    }
 
196
   
 
197
    if (!isalnum(atom) && atom != '-' && atom != '_') {
 
198
      if (isspace(atom)){
 
199
        return ret_val;
 
200
      } else {
 
201
        syntax_error(std::string(_("Unexpected char '")) + atom + "'");
 
202
      }
 
203
    }
 
204
    
 
205
    ret_val += atom;
 
206
  }
 
207
  
 
208
  return ret_val;
 
209
}
 
210
 
 
211
// Jumps to the position of the next token after 'a', no other char's
 
212
// then spaces are allowed before 'a'.
 
213
void
 
214
ConfigParser::jump_after(char c)
 
215
{
 
216
  char atom;
 
217
  
 
218
  jump();
 
219
 
 
220
  atom = get_atom();
 
221
  if (isspace(atom) || atom == c) 
 
222
    {
 
223
      if (atom == c) {
 
224
        return;
 
225
      } else {
 
226
        atom = get_atom();
 
227
        if (atom == c)
 
228
          return;
 
229
      }
 
230
    } 
 
231
  syntax_error(std::string("jump_after(): Expected '") + c + "', got '" + atom + "'" );
 
232
}
 
233
 
 
234
void
 
235
ConfigParser::jump(void)
 
236
{
 
237
  char atom;
 
238
  atom = get_atom();
 
239
 
 
240
  if (isspace(atom)) {
 
241
    return;
 
242
  } else {
 
243
    in.putback(atom);
 
244
  }
 
245
}
 
246
 
 
247
// Print a error message with lineno and filename.
 
248
void
 
249
ConfigParser::syntax_error(std::string error = "")
 
250
{
 
251
  std::string error_str;
 
252
  char tmp[16];
 
253
 
 
254
  snprintf(tmp, 16, "%d\n", lineno);
 
255
  
 
256
  error_str = std::string("PLF: Syntax Error at line ") + tmp;
 
257
 
 
258
  if (error != "")
 
259
    error_str += "PLF:" + error + "\n";
 
260
 
 
261
  PingusError::raise(error_str);
 
262
}
 
263
 
 
264
// Parse the file and fill all structs with the values.
 
265
void
 
266
ConfigParser::parse(void)
 
267
{
 
268
  std::string valueid;
 
269
  std::string value;
 
270
 
 
271
  try 
 
272
    {
 
273
      while(!eof) 
 
274
        {
 
275
          valueid = get_valueid();   
 
276
          jump_after('=');
 
277
          value   = get_value();
 
278
          jump_after(';'); 
 
279
          set_value(valueid, value);
 
280
        }
 
281
    }
 
282
  catch (ConfigParserEOF)
 
283
        {
 
284
        }
 
285
}
 
286
 
 
287
Config::Config()
 
288
{
 
289
  
 
290
}
 
291
 
 
292
Config::Config(std::string f)
 
293
{
 
294
  filename = f;
 
295
  init(filename);
 
296
}
 
297
 
 
298
void
 
299
Config::set_value(const std::string& valueid, const std::string& value)
 
300
{
 
301
  if (valueid == "fullscreen")
 
302
    {
 
303
      fullscreen_enabled = str_to_bool(value);
 
304
    }
 
305
  else if (valueid == "tile-size")
 
306
    {
 
307
      tile_size = str_to_int(value);
 
308
    }
 
309
  else if (valueid == "game-speed")
 
310
    {
 
311
      game_speed = str_to_int(value);
 
312
    }
 
313
  else if (valueid == "print-fps")
 
314
    {
 
315
      print_fps = str_to_bool(value);
 
316
    }
 
317
  else if (valueid == "fast-mode")
 
318
    {
 
319
      fast_mode = str_to_bool(value);
 
320
    }
 
321
  else if (valueid == "maintainer-mode")
 
322
    {
 
323
      maintainer_mode = str_to_bool(value);
 
324
    }
 
325
  else if (valueid == "unlimited-actions")
 
326
    {
 
327
      Cheat::unlimited_actions = str_to_bool(value);
 
328
    }
 
329
  else if (valueid == "cursor-enabled")
 
330
    {
 
331
      cursor_enabled = str_to_bool(value);
 
332
    }
 
333
  else if (valueid == "auto-scrolling")
 
334
    {
 
335
      auto_scrolling = str_to_bool(value);
 
336
    }
 
337
  else if (valueid == "verbose")
 
338
    {
 
339
      verbose = str_to_int(value);
 
340
    }
 
341
  else if (valueid == "width")
 
342
    {
 
343
      screen_width = str_to_int(value);
 
344
    }
 
345
  else if (valueid == "height")
 
346
    {
 
347
      screen_height = str_to_int(value);
 
348
    }
 
349
  else if (valueid == "sound")
 
350
    {
 
351
      sound_enabled = str_to_bool(value);
 
352
    }
 
353
  else if (valueid == "music")
 
354
    {
 
355
      music_enabled = str_to_bool(value);
 
356
    }
 
357
  else if (valueid == "swcursor-enabled")
 
358
    {
 
359
      swcursor_enabled = str_to_bool(value);
 
360
    }
 
361
  else if (valueid == "username")
 
362
    {
 
363
      global_username = valueid;
 
364
    }
 
365
  else if (valueid == "email")
 
366
    {
 
367
      global_email = valueid;
 
368
    }
 
369
  else
 
370
    {
 
371
      PingusError::raise("Config: Unknown valueid: " + valueid);
 
372
    }
 
373
}
 
374
 
 
375
bool
 
376
Config::str_to_bool(const std::string& str)
 
377
{
 
378
  if (str == "true" || str == "1")
 
379
    {
 
380
      return true;
 
381
    }
 
382
  else if (str == "false" || str == "0")
 
383
    {
 
384
      return false;
 
385
    }
 
386
  else
 
387
    {
 
388
      PingusError::raise("Config: value: " + str + " is not of type bool.");
 
389
    }
 
390
    
 
391
  return false; // never reached
 
392
}
 
393
 
 
394
int
 
395
Config::str_to_int(const std::string& str)
 
396
{
 
397
  int ret_val;
 
398
 
 
399
  if (sscanf(str.c_str(), "%d", &ret_val) != 1) 
 
400
    {
 
401
      PingusError::raise("Config: Couldn't convert std::string to integer: " + str);
 
402
    }
 
403
 
 
404
  return ret_val;
 
405
}
 
406
 
 
407
/* EOF */
 
408