Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/util/ini_parser.cc @ 5018

Last change on this file since 5018 was 5018, checked in by bensch, 19 years ago

orxonox/trunk: NO MORE SEGFAULT again :)

File size: 9.4 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: Christian Meyer
14
15   2005-08-14: complete reimplementation:
16               now the File is parsed at the initialisation,
17               and informations is gathered there.
18*/
19
20
21#include "ini_parser.h"
22
23#include "list.h"
24#include "stdlibincl.h"
25#include "debug.h"
26
27using namespace std;
28
29/**
30 *  constructs an IniParser using a file
31 * @param fileName: the path and name of the file to parse
32*/
33IniParser::IniParser (const char* fileName)
34{
35  this->setClassID(CL_INI_PARSER, "IniParser");
36  this->setName(fileName);
37
38  this->currentEntry = NULL;
39  this->currentSection = NULL;
40  this->sections = NULL;
41  if (fileName != NULL)
42    this->readFile(fileName);
43}
44
45/**
46 *  removes the IniParser from memory
47*/
48IniParser::~IniParser ()
49{
50  deleteSections();
51}
52
53/**
54 * removes all the sections. This is like delete, but even cooler :)
55 */
56void IniParser::deleteSections()
57{
58  if (this->sections)
59  {
60    tIterator<IniSection>* sectionIt = this->sections->getIterator();
61    IniSection* sectionEnum = sectionIt->nextElement();
62    while (sectionEnum)
63    {
64      tIterator<IniEntry>* entryIt = sectionEnum->entries->getIterator();
65      IniEntry* entryEnum = entryIt->nextElement();
66      while (entryEnum)
67      {
68        delete []entryEnum->name;
69        delete []entryEnum->value;
70        delete entryEnum;
71        entryEnum = entryIt->nextElement();
72      }
73      delete entryIt;
74
75      delete []sectionEnum->name;
76      delete sectionEnum->entries;
77      delete sectionEnum;
78      sectionEnum = sectionIt->nextElement();
79    }
80    delete sectionIt;
81  }
82  delete this->sections;
83  this->currentEntry = NULL;
84  this->currentSection = NULL;
85  this->sections = NULL;
86}
87
88/**
89 * opens another file to parse
90 * @param fileName: path and name of the new file to parse
91 * @return true on success false otherwise;
92*/
93bool IniParser::readFile(const char* fileName)
94{
95  FILE*    stream;           //!< The stream we use to read the file.
96  if (sections != NULL)
97    deleteSections();
98  if( fileName == NULL)
99    return false;
100
101  printf("1\n");
102  if( (stream = fopen (fileName, "r")) == NULL)
103  {
104    PRINTF(1)("IniParser could not open %s\n", fileName);
105    return false;
106  }
107  else
108  {
109    printf("2\n");
110    this->currentEntry = NULL;
111    this->currentSection = NULL;
112    this->sections = new tList<IniSection>;
113
114    /////////////////////////////
115    // READING IN THE INI-FILE //
116    /////////////////////////////
117    char lineBuffer[PARSELINELENGHT];
118    char buffer[PARSELINELENGHT];
119    char* ptr;
120
121    while( !feof( stream))
122    {
123      // get next line
124      fgets (lineBuffer, PARSELINELENGHT, stream);
125      printf("%s", lineBuffer);
126      // remove newline char, and \0-terminate
127      if( (ptr = strchr( lineBuffer, '\n')) != NULL)
128        *ptr = 0;
129      // check for section identifyer
130      if (strlen(lineBuffer) <= 1)
131        printf("empty Line\n");
132      else if( sscanf (lineBuffer, "[%s", buffer) == 1)
133      {
134        if( (ptr = strchr( buffer, ']')) != NULL)
135        {
136          *ptr = 0;
137          IniSection* newSection = new IniSection;
138          newSection->name = new char[strlen(buffer)+1];
139          strcpy(newSection->name, buffer);
140          newSection->entries = new tList<IniEntry>;
141          this->currentSection = newSection;
142          this->sections->add(newSection);
143        }
144      }
145      // check for Entry identifier (Entry = Value)
146      else if( (ptr = strchr( lineBuffer, '=')) != NULL)
147      {
148        if (currentSection == NULL)
149        {
150          PRINTF(2)("Not in a Section yet for %s\n", lineBuffer);
151          continue;
152        }
153        if( ptr == lineBuffer)
154          continue;
155        char* valueBegin = ptr+1;
156        while ((*valueBegin == ' ' || *valueBegin == '\t') && valueBegin <= lineBuffer + strlen(lineBuffer))
157          ++valueBegin;
158        char* nameBegin = lineBuffer;
159        while ((*nameBegin == ' ' || *nameBegin == '\t') && nameBegin < ptr)
160          ++nameBegin;
161        char* nameEnd = ptr-1;
162        while ((*nameEnd == ' ' || *nameEnd == '\t' ) && nameEnd >= nameBegin)
163          --nameEnd;
164        nameEnd[1] = '\0';
165
166        IniEntry* newEntry = new IniEntry;
167        newEntry->value = new char[strlen(valueBegin)+1];
168        strcpy(newEntry->value, valueBegin);
169        newEntry->name = new char[strlen (nameBegin)+1];
170        strcpy(newEntry->name, nameBegin);
171
172        this->currentSection->entries->add(newEntry);
173      }
174
175    }
176  }
177  fclose(stream);
178  return true;
179}
180
181/**
182 *  set the parsing cursor to the specified section
183 * @param sectionName: the name of the section to set the cursor to
184 * @return true on success or false if the section could not be found
185*/
186bool IniParser::getSection( const char* sectionName)
187{
188  tIterator<IniSection>* sectionIt = this->sections->getIterator();
189  IniSection* sectionEnum = sectionIt->nextElement();
190  while (sectionEnum)
191  {
192    if (!strcmp(sectionEnum->name, sectionName))
193    {
194      this->currentSection = sectionEnum;
195      this->currentEntry = NULL;
196      delete sectionIt;
197      return true;
198    }
199
200    sectionEnum = sectionIt->nextElement();
201  }
202  delete sectionIt;
203  return false;
204}
205
206/**
207 * moves to the first section
208 */
209void IniParser::getFirstSection()
210{
211  if (this->sections)
212    this->currentSection = this->sections->firstElement();
213  else
214    this->currentSection = NULL;
215  this->currentEntry = NULL;
216}
217
218/**
219 * searches the next section
220 * @returns the name of the section if found, NULL otherwise
221 */
222const char* IniParser::nextSection()
223{
224  if (this->currentSection == NULL)
225    return NULL;
226  else
227  {
228    if (this->sections)
229    {
230      if (this->currentSection == this->sections->lastElement())
231        this->currentSection = NULL;
232      else
233        this->currentSection = this->sections->nextElement(this->currentSection);
234    }
235  }
236
237  if (this->currentSection != NULL)
238    return this->currentSection->name;
239  else
240    return NULL;
241}
242
243/**
244 * moves to the first Variable of the current Section
245 */
246void IniParser::getFirstVar()
247{
248  if (this->currentSection)
249    this->currentEntry = this->currentSection->entries->firstElement();
250  else
251    this->currentEntry = NULL;
252}
253
254/**
255 *  gets the next VarName=VarValue pair from the parsing stream
256 * @return true on success, false otherwise (in the latter case name and value will be NULL)
257 */
258bool IniParser::nextVar()
259{
260  if (this->currentSection == NULL
261      || this->currentEntry == NULL
262      || this->currentEntry == this->currentSection->entries->lastElement())
263  {
264    this->currentEntry = NULL;
265    return false;
266  }
267  this->currentEntry = this->currentSection->entries->nextElement(this->currentEntry);
268
269  if (this->currentEntry == NULL)
270    return false;
271  else
272    return true;
273}
274
275/**
276 *  directly acesses an entry in a section
277 * @param entryName: the name of the entry to find
278 * @param sectionName: the section where the entry is to be found
279 * @param defaultValue: what should be returned in case the entry cannot be found
280 * @return a pointer to a buffer conatining the value of the specified entry. This buffer will contain the data specified in defvalue in case the entry wasn't found
281
282   The returned pointer points to an internal buffer, so do not free it on your own. Do not give a NULL pointer to defvalue, this will certainly
283   lead to unwanted behaviour.
284*/
285const char* IniParser::getVar(const char* entryName, const char* sectionName, const char* defaultValue) const
286{
287  if (this->sections)
288  {
289    tIterator<IniSection>* sectionIt = this->sections->getIterator();
290    IniSection* sectionEnum = sectionIt->nextElement();
291    while (sectionEnum)
292    {
293      if (!strcmp(sectionEnum->name, sectionName))
294      {
295        tIterator<IniEntry>* entryIt = sectionEnum->entries->getIterator();
296        IniEntry* entryEnum = entryIt->nextElement();
297        while (entryEnum)
298        {
299          if (!strcmp(entryEnum->name, entryName))
300          {
301            delete entryIt;
302            delete sectionIt;
303            return entryEnum->value;
304          }
305          entryEnum = entryIt->nextElement();
306        }
307         delete entryIt;
308         PRINTF(2)("Entry %s in section %s not found.\n", entryName, sectionName);
309         break;
310      }
311      sectionEnum = sectionIt->nextElement();
312    }
313    delete sectionIt;
314    PRINTF(2)("Section %s that should be containing %s not found.\n", sectionName, entryName);
315  }
316  else
317    PRINTF(1)("%s not opened\n", this->getName());
318
319  return defaultValue;
320
321}
322
323/**
324 * output the whole tree in a nice and easy way.
325 */
326void IniParser::debug() const
327{
328  PRINTF(0)("Iniparser %s - debug\n", this->getName());
329  if (this->sections)
330  {
331    tIterator<IniSection>* sectionIt = this->sections->getIterator();
332    IniSection* sectionEnum = sectionIt->nextElement();
333    while (sectionEnum)
334    {
335      PRINTF(0)(" [%s]\n", sectionEnum->name);
336
337      tIterator<IniEntry>* entryIt = sectionEnum->entries->getIterator();
338      IniEntry* entryEnum = entryIt->nextElement();
339      while (entryEnum)
340      {
341        PRINTF(0)("   :%s: -> '%s'\n", entryEnum->name, entryEnum->value);
342
343        entryEnum = entryIt->nextElement();
344      }
345      delete entryIt;
346
347      sectionEnum = sectionIt->nextElement();
348    }
349    delete sectionIt;
350  }
351  else
352    PRINTF(1)("%s not opened\n", this->getName());
353}
Note: See TracBrowser for help on using the repository browser.