first check-in of feisty meow codebase. many things broken still due to recent
[feisty_meow.git] / core / library / configuration / ini_parser.h
1 #ifndef INI_PARSER_CLASS
2 #define INI_PARSER_CLASS
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : ini_parser                                                        *
7 *  Author : Chris Koeritz                                                     *
8 *                                                                             *
9 *******************************************************************************
10 * Copyright (c) 2000-$now By Author.  This program is free software; you can  *
11 * redistribute it and/or modify it under the terms of the GNU General Public  *
12 * License as published by the Free Software Foundation; either version 2 of   *
13 * the License or (at your option) any later version.  This is online at:      *
14 *     http://www.fsf.org/copyleft/gpl.html                                    *
15 * Please send any updates to: fred@gruntose.com                               *
16 \*****************************************************************************/
17
18 #include "table_configurator.h"
19
20 namespace configuration {
21
22 //! Parses strings in the fairly well-known INI file format.
23 /*!
24   Description of INI file format:
25
26     The format expected in this parser for initialization files allows for
27   three types of entries.  These are section headers, comments and value
28   definitions.
29     Section headers define the start of a list of value definitions.  A
30   section header is a name in brackets, like [startup].
31     A comment is a string of text that will be ignored.  Comments are preceded
32   by an octothorpe ('#') or a semicolon (';').  The parser will keep comments
33   roughly in the same places they were found in the string that was parsed.
34   A comment is allowed to follow a section header on the same line.
35     Value definitions are a pair of strings separated by an equality operator
36   ('=').  The left side of the value definition is referred to here as the
37   variable's name while the right side is referred to as the variable's value.
38   Note that any line which is not a comment or a section header is considered
39   implicitly to be a value definition, even if it does not contain an equals
40   operator.  This is required for parsing certain INI files that don't follow
41   the established format.  Such lines will have an empty string for their
42   value.
43     White space (either tab characters or space characters) are allowed before
44   and after any of these constructs.  Spaces may also exist before and after
45   the equals operator of a value definition, but once the value starts, any
46   white space is considered part of the value.  Trailing white space is not
47   considered part of a variable name, but white space between the characters
48   before the equals operator is signficant.  Any number of carriage returns
49   can separate the lines of the INI file.
50  
51   Here is an example of a valid INI file:
52     @code
53     # Initialization file for Frootnik Corp.
54  
55     [common]  ; all of our programs use these.
56     magnification=1
57  
58     text_color=puce
59     font=atavata
60       ;;; see font/color document in readme.txt.
61  
62     [sourceburger]  ; sourceburger application specific settings
63  
64     crashnow = 0
65     crashlater = 1
66     get clue=0
67     windowtitle = Source Burger 5000
68  
69     danger will robinson
70     @endcode
71 */
72
73 class ini_parser : public table_configurator
74 {
75 public:
76   ini_parser(const basis::astring &to_parse,
77           treatment_of_defaults behavior = RETURN_ONLY);
78     //!< constructs an ini_parser by parsing entries out of "to_parse".
79     /*!< after construction, the success of parsing can be checked using
80     well_formed(). */
81
82   ~ini_parser();
83
84   void reset(const basis::astring &to_parse);
85     //!< drops any existing information and processes the string "to_parse".
86
87   void add(const basis::astring &to_parse);
88     //!< merges items parsed from "to_parse" into the current set.
89     /*!< processes the string "to_parse" as in the reset() method but adds
90     any new sections found to our configuration.  if sections are found with
91     the same names, then the values found in "to_parse" override the ones
92     already listed. */
93
94   bool well_formed() const { return _well_formed; }
95     //!< returns true if the ini file's contents were in the format expected.
96
97   bool restate(basis::astring &new_ini, bool add_spaces = false);
98     //!< stores a cleaned version of the internal state into "new_ini".
99     /*!< if "add_spaces" is true, then the entries will be in the form of
100     'x = y' rather than 'x=y'. */
101
102   void merge_section(const basis::astring &section_name, const structures::string_table &to_merge);
103     //!< merges the table "to_merge" into the "section_name".
104     /*!< any new values from "to_merge" that are not found in the section with
105     "section_name" in "this" object are added and any existing values will be
106     replaced. */
107
108 private:
109   bool _well_formed;  //!< true if the ini file had a valid format.
110   basis::astring *_preface;  //!< information that comes before the first section.
111
112   void chow_through_eol(basis::astring &to_chow);
113     //!< eats up to an EOL character but adds the text to our preface string.
114
115   bool parse_section(basis::astring &to_parse, basis::astring &section_name);
116     //!< looks for a section name in the string "to_parse".
117     /*!< true is returned on success; success means that a "section_name" was
118     found and that "to_parse" has been destructively eaten to remove it. */
119 };
120
121 } //namespace.
122
123 #endif
124