Turn a conditional into an assertion in ConLoad
[openttd/fttd.git] / src / ini_type.h
blobc6f5604f95f3d5400b760687f93c4d8c5955057d
1 /* $Id$ */
3 /*
4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 */
10 /** @file ini_type.h Types related to reading/writing '*.ini' files. */
12 #ifndef INI_TYPE_H
13 #define INI_TYPE_H
15 #include <functional>
17 #include "core/pointer.h"
18 #include "core/forward_list.h"
20 #include "fileio_type.h"
22 /** Base class for named entities (items, groups) in an ini file. */
23 struct IniName {
24 private:
25 const ttd_unique_free_ptr<char> name; ///< the name of this item
27 public:
28 IniName (const char *name, size_t len = 0);
30 const char *get_name (void) const
32 return name.get();
35 bool is_name (const char *name) const
37 return strcmp (this->name.get(), name) == 0;
40 bool is_name (const char *name, size_t len) const
42 return strncmp (this->name.get(), name, len) == 0 && this->name.get()[len] == 0;
45 struct NamePred {
46 const char *const name;
47 const size_t len;
49 NamePred (const char *name, size_t len)
50 : name(name), len(len)
54 bool operator() (const IniName *item) const
56 return item->is_name (this->name, this->len);
62 /** Base class for entity lists (items, groups) in an ini file. */
63 template <typename T>
64 struct IniList : ForwardList <T, true> {
65 /** Clear this IniList. */
66 void clear (void)
68 T *p = this->detach_all();
69 while (p != NULL) {
70 T *next = p->next;
71 delete p;
72 p = next;
76 /** IniList destructor. */
77 ~IniList()
79 this->clear();
82 /**
83 * Find an entry by name.
84 * @param name the name to search for
85 * @return the item by that name, or NULL if none was found
87 T *find (const char *name)
89 return this->find_pred (std::bind2nd (std::mem_fun (&T::IniName::is_name), name));
92 const T *find (const char *name) const
94 return const_cast<IniList*>(this)->find (name);
97 /**
98 * Find an entry by name.
99 * @param name the name to search for
100 * @param len use only this many chars of name
101 * @return the item by that name, or NULL if none was found
103 T *find (const char *name, size_t len)
105 return this->find_pred (typename T::IniName::NamePred (name, len));
108 const T *find (const char *name, size_t len) const
110 return const_cast<IniList*>(this)->find (name, len);
114 * Remove an entry by name.
115 * @param name the name to remove
117 T *remove (const char *name)
119 return this->remove_pred (std::bind2nd (std::mem_fun (&T::IniName::is_name), name));
124 /** Types of groups */
125 enum IniGroupType {
126 IGT_VARIABLES = 0, ///< Values of the form "landscape = hilly".
127 IGT_LIST = 1, ///< A list of values, separated by \n and terminated by the next group block.
128 IGT_SEQUENCE = 2, ///< A list of uninterpreted lines, terminated by the next group block.
131 /** A single "line" in an ini file. */
132 struct IniItem : ForwardListLink<IniItem>, IniName {
133 typedef ForwardList<IniItem>::iterator iterator;
134 typedef ForwardList<IniItem>::const_iterator const_iterator;
136 char *value; ///< The value of this item
137 char *comment; ///< The comment associated with this item
139 IniItem (const char *name, size_t len = 0);
140 ~IniItem();
142 void SetValue(const char *value);
145 /** A group within an ini file. */
146 struct IniGroup : ForwardListLink<IniGroup>, IniName, IniList<IniItem> {
147 typedef ForwardList<IniGroup>::iterator iterator;
148 typedef ForwardList<IniGroup>::const_iterator const_iterator;
150 const IniGroupType type; ///< type of group
151 char *comment; ///< comment for group
153 IniGroup (IniGroupType type, const char *name, size_t len = 0);
154 ~IniGroup();
156 IniItem *get_item (const char *name);
158 IniItem *append (const char *name, size_t len = 0)
160 IniItem *item = new IniItem (name, len);
161 this->IniList<IniItem>::append (item);
162 return item;
166 /** Ini file that only supports loading. */
167 struct IniLoadFile : IniList<IniGroup> {
168 char *comment; ///< last comment in file
169 const char * const *const list_group_names; ///< NULL terminated list with group names that are lists
170 const char * const *const seq_group_names; ///< NULL terminated list with group names that are sequences.
172 IniLoadFile(const char * const *list_group_names = NULL, const char * const *seq_group_names = NULL);
173 virtual ~IniLoadFile();
175 IniGroupType get_group_type (const char *name, size_t len) const;
177 IniGroup *get_group (const char *name, size_t len = 0);
179 IniGroup *append (const char *name, size_t len)
181 IniGroupType type = this->get_group_type (name, len);
182 IniGroup *group = new IniGroup (type, name, len);
183 this->IniList<IniGroup>::append (group);
184 return group;
187 void load (FILE *in, size_t end);
190 * Report an error about the file contents.
191 * @param pre Prefix text of the \a buffer part.
192 * @param buffer Part of the file with the error.
193 * @param post Suffix text of the \a buffer part.
195 virtual void ReportFileError(const char * const pre, const char * const buffer, const char * const post) = 0;
198 /** Ini file that supports both loading and saving. */
199 struct IniFile : IniLoadFile {
200 IniFile (const char *filename, Subdirectory subdir, const char * const *list_group_names = NULL);
202 bool SaveToDisk(const char *filename);
204 virtual void ReportFileError(const char * const pre, const char * const buffer, const char * const post);
207 #endif /* INI_TYPE_H */