~thindil/steamfort/development

1 by thindil
Initial import
1
/*
165 by thindil
update to libtcod version 1.5.1
2
* libtcod 1.5.1
3
* Copyright (c) 2008,2009,2010 Jice & Mingos
1 by thindil
Initial import
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions are met:
8
*     * Redistributions of source code must retain the above copyright
9
*       notice, this list of conditions and the following disclaimer.
10
*     * Redistributions in binary form must reproduce the above copyright
11
*       notice, this list of conditions and the following disclaimer in the
12
*       documentation and/or other materials provided with the distribution.
165 by thindil
update to libtcod version 1.5.1
13
*     * The name of Jice or Mingos may not be used to endorse or promote products
1 by thindil
Initial import
14
*       derived from this software without specific prior written permission.
15
*
165 by thindil
update to libtcod version 1.5.1
16
* THIS SOFTWARE IS PROVIDED BY JICE AND MINGOS ``AS IS'' AND ANY
1 by thindil
Initial import
17
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
165 by thindil
update to libtcod version 1.5.1
19
* DISCLAIMED. IN NO EVENT SHALL JICE OR MINGOS BE LIABLE FOR ANY
1 by thindil
Initial import
20
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
*/
27
28
#ifndef _TCOD_PARSER_HPP
29
#define _TCOD_PARSER_HPP
165 by thindil
update to libtcod version 1.5.1
30
31
/**
32
@PageName parser
33
@PageTitle File parser
34
@PageCategory Base toolkits
35
@PageDesc This toolkit provides an easy way to parse complex text configuration files. It has two main advantages compared to a standard XML SAX parser:
36
	* The configuration file format is more human readable than XML
37
	* The parser knows some data types that it automatically converts to C variables (see <a href="parser_types.html">Standard data types</a>)
38
*/
39
40
/**
41
@PageName parser_format
42
@PageFather parser
43
@PageTitle The libtcod config file format
44
@FuncTitle Comments
45
@FuncDesc Your file can contain single line or multi-line comments :
46
<div class="code"><pre>// This is a single line comment
47
/<span>*</span>
48
   This is a
49
   multi-line comment
50
*<span>/</span>
51
</pre></div>
52
Multi-line comments can be nested :
53
<div class="code"><pre>/<span>*</span>
54
   This is a
55
   multi-line comment containing another
56
   /<span>*</span>
57
&nbsp;&nbsp;&nbsp;&nbsp;multi-line
58
&nbsp;&nbsp;&nbsp;&nbsp;comment
59
   *<span>/</span>
60
*<span>/</span>
61
</pre></div>
62
The parser is not sensible to space characters, tabulations or carriage return except inside strings.
63
*/
64
/**
65
@PageName parser_format
66
@FuncTitle Structures
67
@FuncDesc The libtcod config file format is basically a list of structures. A structure has a type, an optional name and contains properties. The type of the structure defines which properties are allowed / mandatory.
68
<div class="code"><pre>item_type "blade" {            // structure's type : 'item_type'. structure's name : 'blade'
69
	cost=300                   // an integer property
70
	weight=3.5                 // a float property
71
	deal_damage=true           // a boolean property
72
	damages="3d6+2"            // a dice property
73
	col="#FF0000"              // a color property, using #RRGGBB syntax
74
	damaged_color="128,96,96"  // another color property, using rrr,ggg,bbb syntax
75
	damage_type="slash"        // a string property
76
	description="This is a long"
77
	            "description." // a multi-line string property
78
	abstract                   // a flag (simplified boolean property)
79
        intList= [ 1,2,3 ]         // a list of int values
80
        floatList= [ 1.0,2,3.5 ]   // a list of float values
81
        stringList= [ "string1","string2","string3" ]         // a list of string values
82
}
83
</pre></div>
84
A structure can also contain other structures either of the same type, or structures of another type :
85
<div class="code"><pre>item_type "blade" {
86
	item_type "one-handed blades" {
87
		// the item_type "blade" contains another item_type named "one-handed blades"
88
	}
89
	item_type "two-handed blades" {
90
		// the item_type "blade" contains another item_type named "two-handed blades"
91
	}
92
	feature "damage" {
93
		// the item_type "blade" contains another structure, type "feature", name "damage"
94
	}
95
}
96
</pre></div>
97
Sometimes, you don't know the list of properties at compile-time. Fortunately, since libtcod 1.5.1, you can add auto-declaring properties in the file, using one of the type keywords :
98
<div class="code"><pre>item_type "blade" {
99
	bool deal_damage=true
100
	char character='D'
101
	int cost=300
102
	float weight=3.5
103
	string damage_type="slash"
104
	color col="#FF0000"
105
	dice damages="3d6+2"
106
	int[] intList= [ 1,2,3 ]
107
	float[] floatList= [ 1.0,2,3.5 ]
108
	string[] stringList= [ "string1","string2","string3" ]
109
}
110
</pre></div>
111
The properties declared with this syntax were not previously declared for the structure item_type. But since the type is specified, the parser won't reject them. Instead, it will add the property declaration to the structure dynamically (when it parses the file).
112
You can also dynamically create new structures and sub-structures with the struct keyword :
113
<div class="code"><pre>item_type "blade" {
114
    struct component {
115
	    string name="blade"
116
		float weight=1.0
117
	}
118
}
119
</div>
120
With this syntax, you don't need to declare the "component" structure at all in the parser. It will be dynamically registered as the file is parsed.
121
*/
122
123
class TCODLIB_API TCODParser;
124
class TCODLIB_API TCODParserStruct;
125
class TCODLIB_API ITCODParserListener;
126
127
#ifdef TCOD_VISUAL_STUDIO
128
    // silly stuff to avoid VS warning
129
	template class TCODLIB_API TCODList<TCODParserStruct *>;
130
#endif
1 by thindil
Initial import
131
132
class TCODLIB_API TCODParser {
133
public :
165 by thindil
update to libtcod version 1.5.1
134
	/**
135
	@PageName parser_str
136
	@PageTitle Defining the file syntax
137
	@PageFather parser
138
	@FuncTitle Creating a parser
139
	@FuncDesc Use this function to create a generic parser. Then you'll specialize this parser by defining the structures it can read.
140
	@Cpp TCODParser::TCODParser()
141
	@C TCOD_parser_t TCOD_parser_new()
142
	@Py parser_new()
143
	*/
1 by thindil
Initial import
144
	TCODParser();
165 by thindil
update to libtcod version 1.5.1
145
146
	/**
147
	@PageName parser_str
148
	@FuncTitle Registering a new structure type
149
	@Cpp TCODParserStruct *TCODParser::newStructure(const char *name)
150
	@C TCOD_parser_struct_t TCOD_parser_new_struct(TCOD_parser_t parser, char *name)
151
	@Py parser_new_struct(parser, name)
152
	@Param parser	In the C version, the parser handler, returned by TCOD_parser_new.
153
	@Param name	The name of the structure type (in the example, this would be "item_type").
154
	@CppEx
155
		TCODParser parser();
156
		TCODParserStruct *itemTypeStruct = parser.newStructrue("item_type");
157
	@CEx
158
		TCOD_parser_t parser = TCOD_parser_new();
159
		TCOD_parser_struct_t item_type_struct = TCOD_parser_new_struct(parser, "item_type");
160
	@PyEx
161
		parser=libtcod.parser_new()
162
		item_type_struct = libtcod.parser_new_struct(parser, "item_type")
163
	*/
1 by thindil
Initial import
164
	TCODParserStruct *newStructure(const char *name);
165 by thindil
update to libtcod version 1.5.1
165
1 by thindil
Initial import
166
	// register a new custom type
167
	TCOD_value_type_t newCustomType(TCOD_parser_custom_t custom_type_parser);
165 by thindil
update to libtcod version 1.5.1
168
169
	/**
170
	@PageName parser_run
171
	@PageFather parser
172
	@PageTitle Running the parser
173
	@FuncTitle Running the parser
174
	@FuncDesc Once you defined all the structure types and created your listener, you can start the actual parsing of the file :
175
	@Cpp void TCODParser::run(const char *filename, ITCODParserListener *listener = NULL)
176
	@C void TCOD_parser_run(TCOD_parser_t parser, const char *filename, TCOD_parser_listener_t *listener)
177
	@Py parser_run(parser, filename, listener=0)
178
	@Param parser	In the C version, the parser handler, returned by TCOD_parser_new.
179
	@Param filename	The name of the text file to parse, absolute or relative to current directory.
180
	@Param listener	The listener containing the callbacks. Use NULL for the default listener
181
	@Cpp myParser.run("config.txt",new MyListener());
182
	@C TCOD_parser_run(my_parser,"config.txt", my_listener);
183
	@Py libtcod.parser_run(my_parser,"config.txt", MyListener())
184
	*/
185
	void run(const char *filename, ITCODParserListener *listener = NULL);
186
187
	/**
188
	@PageName parser_run
189
	@FuncTitle Destroying the parser
190
	@FuncDesc Once you've done with the file parsing, you can release the resources used by the parser :
191
	@Cpp TCODParser::~TCODParser()
192
	@C void TCOD_parser_delete(TCOD_parser_t parser)
193
	@Py parser_delete(parser)
194
	@Param parser	In the C version, the parser handler, returned by TCOD_parser_new.
195
	*/
196
1 by thindil
Initial import
197
	// error during parsing. can be called by the parser listener
198
	void error(const char *msg, ...);
199
	TCODList<TCODParserStruct *>defs;
200
	bool getBoolProperty(const char *name) const;
201
	int getIntProperty(const char *name) const;
202
	int getCharProperty(const char *name) const;
203
	float getFloatProperty(const char *name) const;
204
	TCODColor getColorProperty(const char *name) const;
205
	TCOD_dice_t getDiceProperty(const char *name) const;
206
	const char * getStringProperty(const char *name) const;
207
	void * getCustomProperty(const char *name) const;
208
	TCOD_list_t getListProperty(const char *name, TCOD_value_type_t type) const;
209
private :
210
	bool parseEntity(TCODParserStruct *def, ITCODParserListener *listener);
211
	TCOD_parser_t data;
212
};
213
165 by thindil
update to libtcod version 1.5.1
214
// a parser structure
215
class TCODLIB_API TCODParserStruct {
216
public :
217
	/**
218
	@PageName parser_str
219
	@FuncTitle Adding a new flag
220
	@FuncDesc Use this function to add a flag property to a structure type. A flag is a simplified boolean property. It cannot be mandatory: either it's present and it's true, or it's absent and it's false.<br />Note that in the C++ version, the function returns its parent object, allowing for chaining.
221
	@Cpp TCODParserStruct* TCODParserStruct::addFlag(const char *name)
222
	@C void TCOD_struct_add_flag(TCOD_parser_struct_t str,char *name)
223
	@Py struct_add_flag(str,name)
224
	@Param str	In the C version, the structure handler, returned by TCOD_parser_new_struct.
225
	@Param name	The name of the flag (in the example, this would be "abstract").
226
	@CppEx itemTypeStruct->addFlag("abstract")->addFlag("static");
227
	@CEx TCOD_struct_add_flag(item_type_struct, "abstract");
228
	@PyEx libtcod.struct_add_flag(item_type_struct, "abstract")
229
	*/
230
	TCODParserStruct* addFlag(const char *propname);
231
232
	/**
233
	@PageName parser_str
234
	@FuncTitle Adding a new property
235
	@FuncDesc Use this function to add a standard property to a structure type. Check standard property types here.<br />Note that in the C++ version, the function returns its parent object, allowing for chaining.
236
	@Cpp TCODParserStruct* TCODParserStruct::addProperty(const char *name, TCOD_value_type_t type, bool mandatory)
237
	@C void TCOD_struct_add_property(TCOD_parser_struct_t str, char *name, TCOD_value_type_t type, bool mandatory)
238
	@Py struct_add_property(str, name, type, mandatory)
239
	@Param str	In the C version, the structure handler, returned by TCOD_parser_new_struct.
240
	@Param name	The name of the property (in the example, this would be "cost" or "damage" or ...).
241
	@Param type	The type of the property. It can be a standard type (see <a href="parser_types.html">this</a>).
242
	@Param mandatory	Is this property mandatory? If true and the property is not defined in the file, the parser will raise an error.
243
	@CppEx
244
		itemTypeStruct->addProperty("cost",TCOD_TYPE_INT,true)
245
		    ->addProperty("weight",TCOD_TYPE_FLOAT,true)
246
		    ->addProperty("deal_damage",TCOD_TYPE_BOOL,true)
247
		    ->addProperty("damaged_color",TCOD_TYPE_COLOR,true);
248
	@CEx
249
		TCOD_struct_add_property(item_type_struct, "cost", TCOD_TYPE_INT, true);
250
		TCOD_struct_add_property(item_type_struct, "damages", TCOD_TYPE_DICE, true);
251
		TCOD_struct_add_property(item_type_struct, "color", TCOD_TYPE_COLOR, true);
252
		TCOD_struct_add_property(item_type_struct, "damaged_color", TCOD_TYPE_COLOR, true);
253
	@PyEx
254
		libtcod.struct_add_property(item_type_struct, "cost", libtcod.TYPE_INT, True)
255
		libtcod.struct_add_property(item_type_struct, "damages", libtcod.TYPE_DICE, True)
256
		libtcod.struct_add_property(item_type_struct, "color", libtcod.TYPE_COLOR, True)
257
		libtcod.struct_add_property(item_type_struct, "damaged_color", libtcod.TYPE_COLOR, True)
258
	*/
259
	TCODParserStruct* addProperty(const char *propname, TCOD_value_type_t type, bool mandatory);
260
261
	/**
262
	@PageName parser_str
263
	@FuncTitle Adding a new value-list property
264
	@FuncDesc A value-list property is a string property for which we define the list of allowed values. The parser will raise an error if the file contains an unauthorized value for this property.
265
		The first value-list property that you add to a structure type will have the TCOD_TYPE_VALUELIST00 type. The next TCOD_TYPE_VALUELIST01. You can define up to 16 value list property for each structure type. The last one has the type TCOD_TYPE_VALUELIST15.
266
		You must provide a value list as a NULL terminated array of strings.<br />Note that in the C++ version, the function returns its parent object, allowing for chaining.
267
	@Cpp TCODParserStruct* TCODParserStruct::addValueList(const char *name, const char **value_list, bool mandatory)
268
	@C void TCOD_struct_add_value_list(TCOD_parser_struct_t str, char *name, char **value_list, bool mandatory)
269
	@Py struct_add_value_list(str, name, value_list, mandatory)
270
	@Param str	In the C version, the structure handler, returned by TCOD_parser_new_struct.
271
	@Param name	The name of the property (in the example, this would be "damage_type").
272
	@Param value_list	The list of allowed strings.
273
	@Param mandatory	Is this property mandatory ? If true and the property is not defined in the file, the parser will raise an error.
274
	@CppEx
275
		static const char *damageTypes[] = { "slash", "pierce", "bludgeon", NULL }; // note the ending NULL
276
		itemTypeStruct->addValueList("damage_type", damageTypes, true);
277
	@CEx
278
		static const char *damage_types[] = { "slash", "pierce", "bludgeon", NULL };
279
		TCOD_struct_add_value_list(item_type_struct, "damage_type", damage_types, true);
280
	@PyEx
281
		damage_types = [ "slash", "pierce", "bludgeon" ]
282
		litbcod.struct_add_value_list(item_type_struct, "damage_type", damage_types, True)
283
	*/
284
	TCODParserStruct* addValueList(const char *propname, const char **value_list, bool mandatory);
285
286
	/**
287
	@PageName parser_str
288
	@FuncTitle Adding a new list property
289
	@FuncDesc Use this function to add a list property to a structure type.<br />Note that in the C++ version, the function returns its parent object, allowing for chaining.
290
	@Cpp TCODParserStruct* TCODParserStruct::addListProperty(const char *name, TCOD_value_type_t type, bool mandatory)
291
	@C void TCOD_struct_add_list_property(TCOD_parser_struct_t str, char *name, TCOD_value_type_t type, bool mandatory)
292
	@Py struct_add_list_property(str, name, type, mandatory)
293
	@Param str	In the C version, the structure handler, returned by TCOD_parser_new_struct.
294
	@Param name	The name of the property (in the example, this would be "cost" or "damages" or ...).
295
	@Param type	The type of the list elements. It must be a standard type (see <a href="parser_types.html">this</a>). It cannot be TCOD_TYPE_LIST.
296
	@Param mandatory	Is this property mandatory ? If true and the property is not defined in the file, the parser will raise an error.
297
	@CppEx
298
		itemTypeStruct->addListProperty("intList",TCOD_TYPE_INT,true)
299
		    ->addListProperty("floatList",TCOD_TYPE_FLOAT,true)
300
		    ->addListProperty("stringList",TCOD_TYPE_STRING,true);
301
	@CEx
302
		TCOD_struct_add_list_property(item_type_struct, "intList", TCOD_TYPE_INT, true);
303
		TCOD_struct_add_list_property(item_type_struct, "floatList", TCOD_TYPE_FLOAT, true);
304
		TCOD_struct_add_list_property(item_type_struct, "stringList", TCOD_TYPE_STRING, true);
305
	@PyEx
306
		libtcod.struct_add_list_property(item_type_struct, "intList", libtcod.TYPE_INT, True)
307
		libtcod.struct_add_list_property(item_type_struct, "floatList", libtcod.TYPE_FLOAT, True)
308
		libtcod.struct_add_list_property(item_type_struct, "stringList", libtcod.TYPE_STRING, True)
309
	*/
310
	TCODParserStruct* addListProperty(const char *propname, TCOD_value_type_t type, bool mandatory);
311
312
	/**
313
	@PageName parser_str
314
	@FuncTitle Adding a sub-structure
315
	@FuncDesc A structure can contain others structures. You can tell the parser which structures are allowed inside one structure type with this function.<br />Note that in the C++ version, the function returns its parent object, allowing for chaining.
316
	@Cpp TCODParserStruct* TCODParserStruct::addStructure(TCODParserStruct *sub_structure)
317
	@C void TCOD_struct_add_structure(TCOD_parser_struct_t str, TCOD_parser_struct_t sub_structure)
318
	@Py struct_add_structure(str, sub_structure)
319
	@Param str	In the C version, the structure handler, returned by TCOD_parser_new_struct.
320
	@Param sub_structure	The structure type that can be embedded.
321
	@CppEx
322
		// The item_type structure can contain itself
323
		itemTypeStruct->addStructure(itemTypeStruct);
324
	@CEx TCOD_struct_add_value_list(item_type_struct, item_type_struct);
325
	@PyEx libtcod.struct_add_value_list(item_type_struct, item_type_struct)
326
	*/
327
	TCODParserStruct* addStructure(TCODParserStruct *sub_entity);
328
329
	/**
330
	@PageName parser_str
331
	@FuncTitle Getting a structure type's name
332
	@FuncDesc You can retrieve the name of the structure type with these functions. Warning ! Do not confuse the structure type's name with the structure's name :
333
		<div class="code"><p>item_type "sword" { ... }</p></div>
334
		Here, the structure type's name is "item_type", the structure name is "sword". Obviously, the structure name cannot be retrieved from the TCODParserStruct object because it's only known at "runtime" (while parsing the file).
335
	@Cpp const char *TCODParserStruct::getName() const
336
	@C const char *TCOD_struct_get_name(TCOD_parser_struct_t str)
337
	@Py struct_get_name(str)
338
	@Param str	In the C version, the structure handler, returned by TCOD_parser_new_struct.
339
	@CppEx const char *structName = itemTypeStruct->getName(); // returns "item_type"
340
	@CEx const char *struct_name = TCOD_struct_get_name(item_type_struct);
341
	@PyEx struct_name = libtcod.struct_get_name(item_type_struct)
342
	*/
343
	const char *getName() const;
344
345
	/**
346
	@PageName parser_str
347
	@FuncTitle Checking if a property is mandatory
348
	@FuncDesc You can know if a property is mandatory :
349
	@Cpp bool TCODParserStruct::isPropertyMandatory(const char *name) const
350
	@C bool TCOD_struct_is_mandatory(TCOD_parser_struct_t str,const char *name)
351
	@Py struct_is_mandatory(str,name)
352
	@Param str	In the C version, the structure handler, returned by TCOD_parser_new_struct.
353
	@Param name	The name of the property, as defined when you called addProperty or addValueList or addListProperty.
354
	@CppEx bool costMandatory = itemTypeStruct->isPropertyMandatory("cost");
355
	@CEx bool cost_mandatory = TCOD_struct_is_mandatory(item_type_struct, "cost");
356
	@PyEx cost_mandatory = libtcod.struct_is_mandatory(item_type_struct, "cost")
357
	*/
358
	bool isPropertyMandatory(const char *propname) const;
359
360
	/**
361
	@PageName parser_str
362
	@FuncTitle Retrieving the type of a property
363
	@FuncDesc You get the type of a property :
364
		In the case of a list property, the value returned is a bitwise or of TCOD_TYPE_LIST and the list element's type. For example, for a list of int, it will return TCOD_TYPE_LIST | TCOD_TYPE_INT.
365
	@Cpp TCOD_value_type_t TCODParserStruct::getPropertyType(const char *name) const
366
	@C TCOD_value_type_t TCOD_struct_get_type(TCOD_parser_struct_t str, const char *name)
367
	@Py struct_get_type(str, name)
368
	@Param str	In the C version, the structure handler, returned by TCOD_parser_new_struct.
369
	@Param name	The name of the property, as defined when you called addProperty or addValueList or addListProperty.
370
	@CppEx
371
		TCOD_value_type_t costType = itemTypeStruct->getPropertyType("cost"); // returns TCOD_TYPE_INT
372
		TCOD_value_type_t intListType = itemTypeStruct->getPropertyType("intList"); // returns TCOD_TYPE_LIST|TCOD_TYPE_INT
373
	@CEx TCOD_value_type_t cost_type = TCOD_struct_get_type(item_type_struct, "cost");
374
	@PyEx cost_type = libtcod.struct_get_type(item_type_struct, "cost")
375
	*/
376
	TCOD_value_type_t getPropertyType(const char *propname) const;
377
378
// private stuff
379
	TCOD_parser_struct_t data;
380
};
381
382
/**
383
 @PageName parser_run
384
 @FuncTitle Creating a listener
385
 @FuncDesc For basic config files, you don't have to write a listener. Instead, use the default listener. The parser uses a SAX-like approach during the parsing of the file. This means that the whole file is not stored in memory in a tree structure. Instead, it works like a stream parser and raises events. Each event has an associated callback that is provided by a listener :
386
 @Cpp
387
	class ITCODParserListener {
388
	public :
389
		virtual bool parserNewStruct(TCODParser *parser,const TCODParserStruct *str,const char *name)=0;
390
		virtual bool parserFlag(TCODParser *parser,const char *name)=0;
391
		virtual bool parserProperty(TCODParser *parser,const char *name, TCOD_value_type_t type, TCOD_value_t value)=0;
392
		virtual bool parserEndStruct(TCODParser *parser,const TCODParserStruct *str, const char *name)=0;
393
		virtual void error(const char *msg) = 0;
394
	};
395
 @C
396
	typedef struct {
397
		bool (*new_struct)(TCOD_parser_struct_t str,const char *name);
398
		bool (*new_flag)(const char *name);
399
		bool (*new_property)(const char *name, TCOD_value_type_t type, TCOD_value_t value);
400
		bool (*end_struct)(TCOD_parser_struct_t str, const char *name);
401
		void (*error)(const char *msg);
402
	} TCOD_parser_listener_t;
403
 @Py
404
	class ParserListener :
405
		def new_struct(str,name) : ...
406
		def new_flag(name) : ...
407
		def new_property(name,type,value) : ...
408
		def end_struct(self, struct, name) : ...
409
		def error(msg) : ...
410
*/
411
/**
412
 @PageName parser_run
413
 @FuncDesc Before running the parser, you have to build a listener :
414
 @Cpp
415
	class MyListener : public ITCODParserListener {
416
		bool parserNewStruct(TCODParser *parser,const TCODParserStruct *str,const char *name) {
417
			printf ("new structure type '%s' with name '%s'\n",str->getname(),name ? name : "NULL");
418
			return true;
419
		}
420
		bool parserFlag(TCODParser *parser,const char *name) {
421
			printf ("found new flag '%s'\n",name);
422
			return true;
423
		}
424
		bool parserProperty(TCODParser *parser,const char *name, TCOD_value_type_t type, TCOD_value_t value) {
425
			printf ("found new property '%s'\n",name);
426
			return true;
427
		}
428
		bool parserEndStruct(TCODParser *parser,const TCODParserStruct *str,const char *name) {
429
			printf ("end of structure type '%s'\n",name);
430
			return true;
431
		}
432
		void error(char *msg) {
433
			fprintf(stderr,msg);
434
			exit(1);
435
		}
436
	};
437
 @C
438
	bool my_parser_new_struct(TCOD_parser_struct_t str, const char *name) {
439
		printf ("new structure type '%s' with name '%s'\n",TCOD_struct_get_name(str),name ? name : "NULL");
440
		return true;
441
	}
442
	bool my_parser_flag(const char *name) {
443
		printf ("found new flag '%s'\n",name);
444
		return true;
445
	}
446
	bool my_parser_property(const char *name, TCOD_value_type_t type, TCOD_value_t value) {
447
		printf ("found new property '%s'\n",name);
448
		return true;
449
	}
450
	bool my_parser_end_struct(TCOD_parser_struct_t str, const char *name) {
451
		printf ("end of structure type '%s'\n",name);
452
		return true;
453
	}
454
	void my_parser_error(const char *msg) {
455
		fprintf(stderr,msg);
456
		exit(1);
457
	}
458
	TCOD_parser_listener_t my_listener = {
459
		my_parser_new_struct,
460
		my_parser_flag,
461
		my_parser_property,
462
		my_parser_end_struct,
463
		my_parser_error
464
	};
465
 @Py
466
    class MyListener:
467
        def new_struct(self, struct, name):
468
            print 'new structure type', libtcod.struct_get_name(struct),
469
                  ' named ', name
470
            return True
471
        def new_flag(self, name):
472
            print 'new flag named ', name
473
            return True
474
        def new_property(self,name, typ, value):
475
            type_names = ['NONE', 'BOOL', 'CHAR', 'INT', 'FLOAT', 'STRING',
476
                          'COLOR', 'DICE']
477
            if typ == libtcod.TYPE_COLOR :
478
                print 'new property named ', name,' type ',type_names[typ],
479
                      ' value ', value.r, value.g, value.b
480
            elif typ == libtcod.TYPE_DICE :
481
                print 'new property named ', name,' type ',type_names[typ],
482
                      ' value ', value.nb_rolls, value.nb_faces,
483
                      value.multiplier, value.addsub
484
            else:
485
                print 'new property named ', name,' type ',type_names[typ],
486
                      ' value ', value
487
            return True
488
        def end_struct(self, struct, name):
489
            print 'end structure type', libtcod.struct_get_name(struct),
490
                  ' named ', name
491
            return True
492
        def error(self,msg):
493
            print 'error : ', msg
494
            return True
495
 */
496
497
// sax event listener
498
class TCODLIB_API ITCODParserListener {
499
public :
500
	virtual ~ITCODParserListener(){}
501
	/**
502
	@PageName parser_run
503
	@FuncTitle Handling 'newStruct' events
504
	@FuncDesc This callback is called each time the parser find a new structure declaration in the file. Example :
505
<div class="code"><pre>item_type "blade" { // <= newStruct event here
506
	...
507
}
508
</pre></div>
509
It must return true if everything is right, false if there is an error and the parser must exit.
510
	@Cpp bool ITCODParserListener::parserNewStruct(TCODParser *parser,TCODParserStruct *str,const char *name)
511
	@C bool new_struct(TCOD_parser_struct_t str,const char *name)
512
	@Py new_struct(str,name)
513
	@Param parser	In the C++ version, the parser object, returned by TCODParser constructor. It's used for error handling.
514
	@Param str	The structure type. Can be used to retrieve the type's name with getName. In the example above, this would be "item_type".
515
	@Param name	The name of the structure or NULL if no name is present in the file. In the example above, this would be "blade".
516
	*/
517
	virtual bool parserNewStruct(TCODParser *parser,const TCODParserStruct *str,const char *name)=0;
518
519
	/**
520
	@PageName parser_run
521
	@FuncTitle Handling 'newFlag' events
522
	@FuncDesc This callback is called each time the parser find a new flag in the file. Example :
523
<div class="code"><pre>item_type "blade" {
524
	abstract  // <= newFlag event here
525
}
526
</pre></div>
527
It must return true if everything is right, false if there is an error and the parser must exit.
528
	@Cpp bool ITCODParserListener::parserFlag(TCODParser *parser,const char *name)
529
	@C bool new_flag(const char *name)
530
	@Py new_flag(name)
531
	@Param parser	In the C++ version, the parser object, returned by TCODParser constructor. It's used for error handling.
532
	@Param name	The name of the flag. In the example, this would be "abstract".
533
	*/
534
	virtual bool parserFlag(TCODParser *parser,const char *name)=0;
535
536
	/**
537
	@PageName parser_run
538
	@FuncTitle Handling 'newProperty' events
539
	@FuncDesc This callback is called each time the parser find a new property in the file. Example :
540
<div class="code"><pre>item_type "blade" {
541
	abstract
542
	cost=300 // <= newProperty event here
543
}
544
</pre></div>
545
It must return true if everything is right, false if there is an error and the parser must exit.
546
	@Cpp bool ITCODParserListener::parserProperty(TCODParser *parser,const char *name, TCOD_value_type_t type, TCOD_value_t value)
547
	@C bool new_property(const char *name, TCOD_value_type_t type, TCOD_value_t value)
548
	@Py new_property(name,type,value)
549
	@Param parser	In the C++ version, the parser object, returned by TCODParser constructor. It's used for error handling.
550
	@Param name	The name of the property. In the example, this would be "cost".
551
	@Param type	The type of the property as defined when you called addProperty or addValueList. In the example, this would be TCOD_TYPE_INT.
552
	@Param value	The value of the property, stored in a generic value structure. In the example, we would have value.i == 300.
553
In the case of a value-list property, the type would reflect the list id (between TCOD_TYPE_VALUELIST00 and TCOD_TYPE_VALUELIST15) and value.s would contain the actual string.
554
	*/
555
	virtual bool parserProperty(TCODParser *parser,const char *propname, TCOD_value_type_t type, TCOD_value_t value)=0;
556
557
	/**
558
	@PageName parser_run
559
	@FuncTitle Handling 'endStruct' events
560
	@FuncDesc This callback is called each time the parser find the end of a structure declaration in the file. Example :
561
<div class="code"><pre>item_type "blade" {
562
	...
563
} // <= endStruct event here
564
</pre></div>
565
It must return true if everything is right, false if there is an error and the parser must exit.
566
	@Cpp bool ITCODParserListener::parserEndStruct(TCODParser *parser,TCODParserStruct *str,const char *name)
567
	@C bool end_struct(TCOD_parser_struct_t str,const char *name)
568
	@Py end_struct(str,name)
569
	@Param parser	In the C++ version, the parser object, returned by TCODParser constructor. It's used for error handling.
570
	@Param str	The structure type. Can be used to retrieve the type's name with getName. In the example above, this would be "item_type".
571
	@Param name	The name of the structure or NULL if no name is present in the file. In the example above, this would be "blade".
572
	*/
573
	virtual bool parserEndStruct(TCODParser *parser,const TCODParserStruct *str, const char *name)=0;
574
575
	/**
576
	@PageName parser_run
577
	@FuncTitle Handling errors
578
	@FuncDesc There are two kind of errors :
579
    * Errors that are detected by the parser itself (malformed file, bad value syntax for a property, missing mandatory property in a structure, ...).
580
    * Errors that you detect in your callbacks.
581
	When the parser finds an error in the file, it will call the error callback and stop :
582
	@Cpp void ITCODParserListener::error(const char *msg)
583
	@C void error(const char *msg)
584
	@Py error(msg)
585
	@Param msg	The error message from the parser with the file name and the line number.
586
	*/
587
588
	/**
589
	@PageName parser_run
590
	@FuncDesc If you find an error in your callback, you have to call the parser error function. It will add the file name and line number to your error message, and then call your error callback :
591
The code in the example below will result in your error callback called with the following string :
592
"error in &lt;filename&gt; line &lt;line_number&gt; : Bad cost value %d. Cost must be between 0 and 1000"
593
	@Cpp void TCODParser::error(const char *msg, ...)
594
	@C void TCOD_parser_error(const char *msg, ...)
595
	@Py parser_error(msg)
596
	@Param msg	printf-like format string for your error message.
597
	@CppEx parser->error("Bad cost value %d. Cost must be between 0 and 1000", value.i);
598
	@CEx TCOD_parser_error("Bad cost value %d. Cost must be between 0 and 1000", value.i);
599
	@PyEx libtcod.parser_error("Bad cost value %d. Cost must be between 0 and 1000"%( value ))
600
	*/
601
	virtual void error(const char *msg) = 0;
602
};
603
604
/**
605
 @PageName parser_types
606
 @PageFather parser
607
 @PageTitle Standard types
608
 @FuncDesc The parser can parse natively several data types. It stores them in a generic union :
609
 @C
610
	typedef struct {
611
		int nb_rolls;
612
		int nb_faces;
613
		float multiplier;
614
		float addsub;
615
	} TCOD_dice_t;
616
617
	typedef union {
618
		bool b;
619
		char c;
620
		int32 i;
621
		float f;
622
		char *s;
623
		TCOD_color_t col;
624
		TCOD_dice_t dice;
625
		TCOD_list_t list;
626
		void *custom;
627
	} TCOD_value_t;
628
*/
629
/**
630
 @PageName parser_types
631
 @FuncDesc Possible types are defined by the TCOD_value_type_t enumeration :
632
For python, remove TCOD_ : libtcod.TYPE_BOOL
633
<table class="param">
634
<tbody><tr><th>TCOD_value_type_t</th><th>Value in file</th><th>TCOD_value_t</th></tr>
635
636
<tr><td>TCOD_TYPE_BOOL</td><td>true<br>false</td><td>value.b == true/false</td></tr>
637
<tr><td>TCOD_TYPE_CHAR</td><td>decimal notation : 0 .. 255<br>
638
hexadecimal notation : 0x00 .. 0xff <br>
639
char notation : 'a' ';' ...<br>
640
Special characters :<br>
641
'\n' : carriage return (ascii 13)<br>
642
'\t' : tabulation (ascii 9)<br>
643
644
'\r' : line feed (ascii 10)<br>
645
'\\' : antislash (ascii 92)<br>
646
'\"' : double-quote (ascii 34)<br>
647
'\'' : simple quote (ascii 39)<br>
648
'\xHH' : hexadecimal value, same as 0xHH, HH between 0 and FF<br>
649
'\NNN' : octal value, NNN between 0 and 377<br>
650
</td><td>value.c == The corresponding ascii code</td></tr>
651
<tr><td>TCOD_TYPE_INT</td><td>decimal notation : -2147483648 .. 2147483647<br>hexadecimal notation : 0x0 .. 0xFFFFFFFF</td><td>value.i == the integer value</td></tr>
652
653
<tr><td>TCOD_TYPE_FLOAT</td><td>Any format parsable by atof. Examples:<br>3.14159<br>1.25E-3</td><td>value.f == the float value</td></tr>
654
<tr><td>TCOD_TYPE_STRING</td><td>A double-quote delimited string :<br>"This is a string"<br>Support the same special characters as TCOD_TYPE_CHAR.</td><td>value.s == the corresponding string.<br>Warning ! If you want to store this string, you have to duplicate it (with strdup) as it will be overwritten by the parser</td></tr>
655
<tr><td>TCOD_TYPE_COLOR</td><td>decimal notation : "16,32,64"<br>hexadecimal notation : "#102040"</td><td>value.col == the color.</td></tr>
656
657
<tr><td>TCOD_TYPE_DICE</td><td>[multiplier (x|*)] nb_rolls (d|D) nb_faces [(+|-) addsub] :<br>"3d6"<br>"3D6+2"<br>"0.5x3d6-2"<br>"2*3d8"</td><td>value.dice == the dice components</td></tr>
658
<tr><td>TCOD_TYPE_VALUELISTxx</td><td>Same as TCOD_TYPE_STRING</td><td>value.s == the string value from the value list</td></tr>
659
<tr><td>TCOD_TYPE_LIST</td><td>[ &lt;value1&gt;,&lt;value2&gt;,... ]</td><td>value.list == the TCOD_list_t containing the elements</td></tr>
660
661
</tbody></table>
662
663
To define a list type, use the appropriate function (TCODParserStruct::addListProperty / TCOD_parser_add_list_property) and specify the type of the elements in the list. Lists of list are not supported.
664
 */
665
1 by thindil
Initial import
666
667
#endif