1 #ifndef PARSER_HEADER_FILE_INCLUDED
2 #define PARSER_HEADER_FILE_INCLUDED
3 
4 #undef DEBUG_PARSER
5 
6 /* put it in here for now - later should probably be moved
7    into configure stuff */
8 #define WITH_CONFIG_WRITER
9 
10 #include "afterstep.h"
11 #include "freestor.h"
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 struct SyntaxDef;
18 struct ASHashTable;
19 struct xml_elem_t;
20 
21 typedef enum ASValueType
22 {
23  TT_ANY					=0,
24  TT_FLAG				,
25  TT_INTEGER  			,
26  TT_UINTEGER  			,
27  TT_COLOR    			,
28  TT_FONT    			,
29  TT_FILENAME 			,
30  TT_PATHNAME 			,
31  TT_GEOMETRY 			,
32  TT_TEXT     			,
33 
34  TT_QUOTED_TEXT 		,
35  TT_OPTIONAL_PATHNAME   ,   /* optional quoted text - could be empty */
36  TT_ICON_LIST   		,
37  TT_DIRECTION   		,   /* North,South, East,West, NorthWest, NorthEast, SouthWest, SouthEast */
38  TT_ComplexTypeStart,
39  TT_FUNCTION    		=TT_ComplexTypeStart,
40  TT_BOX	       			,	/* like for IconBox : left top right bottom */
41  TT_BUTTON      		,	/* BUTTON DEFINITION */
42  TT_BINDING     		,	/* key or mouse binding */
43  TT_BITLIST     		,	/* comma or space separated list of bit numbers to set */
44  TT_INTARRAY    		,	/* array of the integer numbers */
45 
46  TT_CURSOR      		,   /* ASCursor - pair of filenames */
47  TT_COMMENT				,
48  TT_INLINE_COMMENT 		,
49  TT_VALUE_TYPES
50 }ASValueType;
51 
52 typedef struct TermDef
53 {
54   /* the following needs to be defined by module */
55 #define TF_SYNTAX_TERMINATOR    (1<<31)	/* will tell parser that reading of config */
56   /* in context of current syntax completed */
57   /* for example ~MyStyle ends MyStyle syntax */
58   /* reading */
59 #define TF_INDEXED              (1<<30)	/* if we have array of indexed items of the same */
60   /* type and ID */
61 #define TF_PHONY	  		 (1<<28)	/* to enable error notification */
62 #define TF_DONT_SPLIT           (1<<29)	/* if it is desired to preserv data intact */
63   /* vs. splitting it into space separated words */
64 #define TF_NO_MYNAME_PREPENDING	(1<<28)	/* has effect only when writing this back to */
65   /* config file */
66 #define TF_SPECIAL_PROCESSING 	(1<<27)	/* supplied special processing procedure */
67   /* needs to be called for this one */
68 #define TF_DONT_REMOVE_COMMENTS (1<<26)	/* indicates that comments sould not be */
69   /* removed from the end of this term */
70 #define TF_NAMED	(1<<25)	/* first token is used as the name */
71   /* rest of the line gets parsed using subsyntax */
72   /* usefull in things like database where you have: Style "name" <blah,blah,blah> */
73   /* <blah,blah,blah> in that case in this case will be parsed using the subsyntax */
74   /* and will be placed in the subtree of FreeStorageElems */
75 #define TF_OBSOLETE		(1<<24)	/* to enable error notification */
76   /* for obsolete options */
77 #define TF_DEPRECIATED		(1<<23)	/* to enable filtering out and preprocessing */
78   /* for depreciated options */
79   /* this options should not be supported by ASCP */
80   /* and must be filtered out and converted into */
81   /* respective non-depreciated options by libASConfig */
82 #define TF_DIRECTION_INDEXED (1<<22) /* North,South, East,West, NorthWest, NorthEast, SouthWest, SouthEast as index */
83 #define TF_NONUNIQUE 		 (1<<21) /* Ther could be several options of this type in config */
84 #define TF_QUOTES_OPTIONAL 	 (1<<20) /* Ther could be several options of this type in config */
85 #define TF_SYNTAX_START		 (1<<19)
86 #define TF_USE_TOKENS_MASK	 (0x07<<16)
87 #define TF_USE_TOKENS(count)  	(((count)<<16)&TF_USE_TOKENS_MASK)
88 #define GetTermUseTokensCount(pterm)  	(((pterm)->flags&TF_USE_TOKENS_MASK)>>16)
89 #define TF_POP_SYNTAX		 (0x01<<15)
90 
91   unsigned long flags;		/* combination of any of above values */
92   char *keyword;
93   unsigned int keyword_len;
94 
95   /* with this one */
96   int type;			/* term's type */
97 
98 /* that is done for some global config id's */
99   /* all module's custom ID's should start from here */
100 #define ID_ANY			0
101 #define TT_CUSTOM_ID_START    	1024
102   int id;			/* term's id */
103   struct SyntaxDef *sub_syntax;	/* points to the SyntaxDef structure
104 					   of the syntax of complicated
105 					   construct like PagerDecoration or
106 					   MyStyle,
107 					   NULL if term has simple structure
108 					 */
109 	ptrdiff_t	struct_field_offset ;
110 	ASFlagType  flags_on, flags_off ;
111 }
112 TermDef;
113 
114 #define TERM_HASH_SIZE      61
115 typedef unsigned short int HashValue;
116 
117 
118 typedef struct SyntaxDef
119 {
120   /* user initialized members */
121   char terminator;		/* character, terminating single term */
122   char file_terminator;		/* character, terminating configuration */
123   TermDef *terms;		/* array of Term definitions */
124   HashValue term_hash_size;	/* defaults to TERM_HASH_SIZE if set to 0 */
125 
126   /* writing beautification and error message members: */
127   char token_separator;
128   /* all of the following must not be NULL */
129   char *prepend_one;		/* sequence of character to prepend single term with */
130   char *prepend_sub;		/* sequence of character to prepend whole config with */
131   char *display_name;		/* will be in error message */
132   char *doc_path;
133   char *display_purpose;    /* purpose of what is identifyed by display_name */
134 
135   /* generated members */
136   struct ASHashTable *term_hash;	/* hash table for fast term search */
137   int recursion;		/* prevents endless recursion in nested constructs */
138 }SyntaxDef;
139 
140 typedef struct SyntaxStack
141 {
142   SyntaxDef *syntax;
143   struct SyntaxStack *next;
144   TermDef *current_term;
145   unsigned long current_flags;
146 }SyntaxStack;
147 
148 typedef struct ASTreeStorageModel
149 {
150 	struct ASTreeStorageModel  *next;
151 	struct ASTreeStorageModel  *child;
152 }ASTreeStorageModel;
153 
154 typedef struct StorageStack
155 {
156   void  *storage;
157   struct StorageStack *next;	/* to enable stackable treatment in case of sub_syntax */
158 }StorageStack;
159 
160 
161 /* that is not supposed to be used outside of this code */
162 /* making it available just in case */
163 #define DISABLED_KEYWORD        "#~~DISABLED~~#"
164 #define DISABLED_KEYWORD_SIZE	14
165 
166 #define MAX_CONFIG_LINE 	MAXLINELENGTH
167 #define NORMAL_CONFIG_LINE 	128
168 
169 
170 typedef struct FilePtrAndData
171 {
172 	FILE *fp ;
173 	char *data ;                               /* prefetched line from the above file ! */
174 }FilePtrAndData;
175 
176 struct ConfigDef;
177 typedef unsigned long (*SpecialFunc) (struct ConfigDef * conf_def);
178 
179 typedef struct ConfigDef
180 {
181   char *myname;			/* prog name */
182 
183   SpecialFunc special;
184   int fd;
185   FILE *fp;			/* this one for compatibility with some old code - most
186 				 * notably balloons and MyStyle
187 				 * when they'll be converted on new style - that should go away
188 				 */
189 
190 #define CP_NeedToCloseFile   (0x01<<0)
191 #define CP_ReadLines         (0x01<<1)
192 #define CP_NeedToFCloseFile  (0x01<<2)
193 
194 #define CP_IgnoreForeign	 (0x01<<8)
195 #define CP_IgnorePublic		 (0x01<<9)
196 #define CP_IgnoreUnknown	 (0x01<<10)
197   ASFlagType flags ;
198   /* allocated to store lines read from the file */
199   char *buffer;
200   long buffer_size;
201   long bytes_in;
202   /* this is the current parsing information */
203   char *tline, *tline_start, *tdata;
204   TermDef *current_term;
205   SyntaxStack *current_syntax;
206   SyntaxDef *syntax;		/* for easier handling only */
207   struct StorageStack *current_tail;
208   char *current_prepend;
209   int current_prepend_size, current_prepend_allocated;
210   char *current_data;
211   long current_data_size;
212   int current_data_len;
213 
214 #define CF_NONE			0
215 #define CF_DISABLED_OPTION	(1<<0)	/* option has #~~DISABLE~~# prepending it */
216 #define CF_PUBLIC_OPTION	(1<<1)	/* public options - with no * MyName prepending it */
217 #define CF_FOREIGN_OPTION	(1<<2)	/* option had * prepending it, but unknown MyName after that */
218 #define CF_LAST_OPTION	(1<<3)	/* option is last in the config file */
219 #define CF_COMMENTED_OPTION	(1<<4)	/* option is last in the config file */
220 #define CF_PHONY_OPTION	(1<<5)	/* option is last in the config file */
221 
222 #define IsOptionEnabled(config)		(!get_flags(config->current_flags,CF_DISABLED_OPTION))
223 #define IsOptionDisabled(config)	  get_flags(config->current_flags,CF_DISABLED_OPTION)
224 #define IsPublicOption(config)		  get_flags(config->current_flags,CF_PUBLIC_OPTION)
225 #define IsPrivateOption(config)		(!get_flags(config->current_flags,CF_PUBLIC_OPTION))
226 #define IsMyOption(config)			(!get_flags(config->current_flags,CF_FOREIGN_OPTION))
227 #define IsForeignOption(config)		  get_flags(config->current_flags,CF_FOREIGN_OPTION)
228 #define IsLastOption(config)		  get_flags(config->current_flags,CF_LAST_OPTION)
229   unsigned long current_flags;
230 
231   char *cursor;
232   int line_count;
233 
234 	void (*statement_handler) (struct ConfigDef * config);
235 }
236 ConfigDef;
237 
238 
239 typedef enum
240 {
241   CDT_Filename,
242   CDT_FilePtr,
243   CDT_FileDesc,
244   CDT_Data,
245   CDT_FilePtrAndData
246 }
247 ConfigDataType;
248 
249 typedef union
250 {
251 	void *vptr ;
252 	const char *filename;
253 	FILE *fileptr ;
254 	int *filedesc ;
255 	char *data ;
256 	FilePtrAndData *fileptranddata ;
257 }ConfigData ;
258 
259 void register_keyword_id( const char *keyword, int id );
260 const char* keyword_id2keyword( int id );
261 void flush_keyword_ids();
262 
263 
264 void BuildHash (SyntaxDef * syntax);
265 void PrepareSyntax (SyntaxDef * syntax);
266 void FreeSyntaxHash (SyntaxDef * syntax);
267 
268 TermDef *FindTerm (SyntaxDef * syntax, int type, int id);
269 TermDef *FindStatementTerm (char *tline, SyntaxDef * syntax);
270 
271 int PopSyntax (ConfigDef * config);
272 int PopStorage (ConfigDef * config);
273 char *GetNextStatement (ConfigDef * config);
274 
275 ConfigDef *InitConfigReader (char *myname, SyntaxDef * syntax,
276 				 ConfigDataType type, ConfigData source,
277 				 SpecialFunc special);
278 int config2tree_storage (ConfigDef * config, ASTreeStorageModel **tail);
279 int ParseConfig (ConfigDef * config, FreeStorageElem ** tail);
280 FreeStorageElem *file2free_storage(const char *filename, char *myname, SyntaxDef *syntax, SpecialFunc special, FreeStorageElem **foreign_options );
281 FreeStorageElem *tline_subsyntax_parse(const char *keyword, char *tline, FILE * fd, char *myname, SyntaxDef *syntax, SpecialFunc special, FreeStorageElem **foreign_options);
282 
283 void ProcessStatement(ConfigDef *config);
284 
285 ConfigDef *InitConfigWriter (char *myname, SyntaxDef * syntax,
286 				 ConfigDataType type, ConfigData  source);
287 
288 #define WF_DISCARD_NONE   	0
289 #define WF_DISCARD_PUBLIC	(1<<1)
290 #define WF_DISCARD_FOREIGN	(1<<2)
291 #define WF_DISCARD_COMMENTS 	(1<<3)
292 #define WF_DISCARD_UNKNOWN	(1<<4)
293 #define WF_DISCARD_EVERYTHING   0xFFFFFFFF
294 long WriteConfig (ConfigDef * config, FreeStorageElem * storage,
295 		  ConfigDataType target_type, ConfigData *target,
296 		  unsigned long flags);
297 void DestroyConfig (ConfigDef * config);
298 
299 int WriteFreeStorageToFile (const char *filename, const char *myname, SyntaxDef *syntax, FreeStorageElem *fs, ASFlagType flags);
300 
301 
302 
303 /* debugging stuff */
304 #ifdef DEBUG_PARSER
305 void PrintConfigReader (ConfigDef * config);
306 #else
307 #define PrintConfigReader(a)
308 #define PrintFreeStorage(b)
309 #endif
310 
311 #define COMMENTS_CHAR '#'
312 #define MYNAME_CHAR   '*'
313 
314 /* utility funcs : */
315 void print_trimmed_str( char *prompt, char * str );
316 void ProcessSubSyntax (ConfigDef * config, void *storage, SyntaxDef * syntax);
317 void PushStorage (ConfigDef * config, void *storage);
318 int PopStorage (ConfigDef * config);
319 void PushSyntax (ConfigDef * config, SyntaxDef * syntax);
320 
321 void config_error (ConfigDef * config, char *err_text);
322 char         *parser_add_terminator (char *ptr, char terminator);
323 
324 struct WriteBuffer
325 {
326 	char         *buffer;
327 	size_t        allocated, used;
328 };
329 
330 void WriteBlock (struct WriteBuffer *t_buffer, char *block_start, char *block_end);
331 extern char         *_disabled_keyword;
332 extern char         *_unknown_keyword;
333 
334 
335 
336 struct xml_elem_t* file2xml_tree(const char *filename, char *myname, SyntaxDef *syntax );
337 
338 typedef enum ASXmlOptIDType
339 {
340 	ASXmlIDT_Index = 0,
341 	ASXmlIDT_Side,
342 	ASXmlIDT_Name,
343 	ASXmlIDT_Types,
344 	ASXmlIDT_None = ASXmlIDT_Types
345 }ASXmlOptIDType;
346 
347 
348 typedef struct ASXmlOptionTreeContext
349 {
350 #define ASXmlOptTree_ExcludeForeign			(0x01<<0)
351 #define ASXmlOptTree_ExcludePublic			(0x01<<1)
352 	ASFlagType flags;
353 
354 	SyntaxDef  *syntax ;
355 	struct xml_elem_t *container, *root ;
356 	char *module;
357 
358 	struct xml_elem_t *current ;
359 #define MAX_XMLATRR_LENGTH		256
360 	ASXmlOptIDType current_id_type;
361 	char  current_id[MAX_XMLATRR_LENGTH+1];
362 	char  current_module[MAX_XMLATRR_LENGTH+1];
363 	char  current_keyword[MAX_XMLATRR_LENGTH+1];
364 	char  current_cdata[MAXLINELENGTH];
365 
366 #define ASXmlOptTree_Foreign			ASXmlOptTree_ExcludeForeign
367 #define ASXmlOptTree_Public		   		ASXmlOptTree_ExcludePublic
368 	ASFlagType current_flags;
369 
370 }ASXmlOptionTreeContext;
371 
372 ASXmlOptionTreeContext *xml_opt_tree_start_traversing( SyntaxDef  *syntax, struct xml_elem_t **pcontainer, struct xml_elem_t *subtree, const char *module );
373 ASXmlOptionTreeContext *file2xml_tree_context( const char *filename, char *myname, SyntaxDef *syntax );
374 void destroy_xml_opt_tree_context( ASXmlOptionTreeContext **pcontext );
375 Bool xml_opt_tree_go_first( ASXmlOptionTreeContext *context );
376 Bool xml_opt_tree_go_next( ASXmlOptionTreeContext *context );
377 
378 
379 
380 
381 #ifdef __cplusplus
382 }
383 #endif
384 
385 
386 #endif
387