1/* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20/*
21 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22 * file for a list of people on the GLib Team.  See the ChangeLog
23 * files for a list of changes.  These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 */
26
27#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
28#error "Only <glib.h> can be included directly."
29#endif
30
31#ifndef __G_SCANNER_H__
32#define __G_SCANNER_H__
33
34#include <glib/gdataset.h>
35#include <glib/ghash.h>
36
37G_BEGIN_DECLS
38
39typedef struct _GScanner	GScanner;
40typedef struct _GScannerConfig	GScannerConfig;
41typedef union  _GTokenValue     GTokenValue;
42
43typedef void		(*GScannerMsgFunc)	(GScanner      *scanner,
44						 gchar	       *message,
45						 gboolean	error);
46
47/* GScanner: Flexible lexical scanner for general purpose.
48 */
49
50/* Character sets */
51#define G_CSET_A_2_Z	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
52#define G_CSET_a_2_z	"abcdefghijklmnopqrstuvwxyz"
53#define G_CSET_DIGITS	"0123456789"
54#define G_CSET_LATINC	"\300\301\302\303\304\305\306"\
55			"\307\310\311\312\313\314\315\316\317\320"\
56			"\321\322\323\324\325\326"\
57			"\330\331\332\333\334\335\336"
58#define G_CSET_LATINS	"\337\340\341\342\343\344\345\346"\
59			"\347\350\351\352\353\354\355\356\357\360"\
60			"\361\362\363\364\365\366"\
61			"\370\371\372\373\374\375\376\377"
62
63/* Error types */
64typedef enum
65{
66  G_ERR_UNKNOWN,
67  G_ERR_UNEXP_EOF,
68  G_ERR_UNEXP_EOF_IN_STRING,
69  G_ERR_UNEXP_EOF_IN_COMMENT,
70  G_ERR_NON_DIGIT_IN_CONST,
71  G_ERR_DIGIT_RADIX,
72  G_ERR_FLOAT_RADIX,
73  G_ERR_FLOAT_MALFORMED
74} GErrorType;
75
76/* Token types */
77typedef enum
78{
79  G_TOKEN_EOF			=   0,
80
81  G_TOKEN_LEFT_PAREN		= '(',
82  G_TOKEN_RIGHT_PAREN		= ')',
83  G_TOKEN_LEFT_CURLY		= '{',
84  G_TOKEN_RIGHT_CURLY		= '}',
85  G_TOKEN_LEFT_BRACE		= '[',
86  G_TOKEN_RIGHT_BRACE		= ']',
87  G_TOKEN_EQUAL_SIGN		= '=',
88  G_TOKEN_COMMA			= ',',
89
90  G_TOKEN_NONE			= 256,
91
92  G_TOKEN_ERROR,
93
94  G_TOKEN_CHAR,
95  G_TOKEN_BINARY,
96  G_TOKEN_OCTAL,
97  G_TOKEN_INT,
98  G_TOKEN_HEX,
99  G_TOKEN_FLOAT,
100  G_TOKEN_STRING,
101
102  G_TOKEN_SYMBOL,
103  G_TOKEN_IDENTIFIER,
104  G_TOKEN_IDENTIFIER_NULL,
105
106  G_TOKEN_COMMENT_SINGLE,
107  G_TOKEN_COMMENT_MULTI,
108  G_TOKEN_LAST
109} GTokenType;
110
111union	_GTokenValue
112{
113  gpointer	v_symbol;
114  gchar		*v_identifier;
115  gulong	v_binary;
116  gulong	v_octal;
117  gulong	v_int;
118  guint64       v_int64;
119  gdouble	v_float;
120  gulong	v_hex;
121  gchar		*v_string;
122  gchar		*v_comment;
123  guchar	v_char;
124  guint		v_error;
125};
126
127struct	_GScannerConfig
128{
129  /* Character sets
130   */
131  gchar		*cset_skip_characters;		/* default: " \t\n" */
132  gchar		*cset_identifier_first;
133  gchar		*cset_identifier_nth;
134  gchar		*cpair_comment_single;		/* default: "#\n" */
135
136  /* Should symbol lookup work case sensitive?
137   */
138  guint		case_sensitive : 1;
139
140  /* Boolean values to be adjusted "on the fly"
141   * to configure scanning behaviour.
142   */
143  guint		skip_comment_multi : 1;		/* C like comment */
144  guint		skip_comment_single : 1;	/* single line comment */
145  guint		scan_comment_multi : 1;		/* scan multi line comments? */
146  guint		scan_identifier : 1;
147  guint		scan_identifier_1char : 1;
148  guint		scan_identifier_NULL : 1;
149  guint		scan_symbols : 1;
150  guint		scan_binary : 1;
151  guint		scan_octal : 1;
152  guint		scan_float : 1;
153  guint		scan_hex : 1;			/* `0x0ff0' */
154  guint		scan_hex_dollar : 1;		/* `$0ff0' */
155  guint		scan_string_sq : 1;		/* string: 'anything' */
156  guint		scan_string_dq : 1;		/* string: "\\-escapes!\n" */
157  guint		numbers_2_int : 1;		/* bin, octal, hex => int */
158  guint		int_2_float : 1;		/* int => G_TOKEN_FLOAT? */
159  guint		identifier_2_string : 1;
160  guint		char_2_token : 1;		/* return G_TOKEN_CHAR? */
161  guint		symbol_2_token : 1;
162  guint		scope_0_fallback : 1;		/* try scope 0 on lookups? */
163  guint		store_int64 : 1; 		/* use value.v_int64 rather than v_int */
164  guint		padding_dummy;
165};
166
167struct	_GScanner
168{
169  /* unused fields */
170  gpointer		user_data;
171  guint			max_parse_errors;
172
173  /* g_scanner_error() increments this field */
174  guint			parse_errors;
175
176  /* name of input stream, featured by the default message handler */
177  const gchar		*input_name;
178
179  /* quarked data */
180  GData			*qdata;
181
182  /* link into the scanner configuration */
183  GScannerConfig	*config;
184
185  /* fields filled in after g_scanner_get_next_token() */
186  GTokenType		token;
187  GTokenValue		value;
188  guint			line;
189  guint			position;
190
191  /* fields filled in after g_scanner_peek_next_token() */
192  GTokenType		next_token;
193  GTokenValue		next_value;
194  guint			next_line;
195  guint			next_position;
196
197  /* to be considered private */
198  GHashTable		*symbol_table;
199  gint			input_fd;
200  const gchar		*text;
201  const gchar		*text_end;
202  gchar			*buffer;
203  guint			scope_id;
204
205  /* handler function for _warn and _error */
206  GScannerMsgFunc	msg_handler;
207};
208
209GScanner*	g_scanner_new			(const GScannerConfig *config_templ);
210void		g_scanner_destroy		(GScanner	*scanner);
211void		g_scanner_input_file		(GScanner	*scanner,
212						 gint		input_fd);
213void		g_scanner_sync_file_offset	(GScanner	*scanner);
214void		g_scanner_input_text		(GScanner	*scanner,
215						 const	gchar	*text,
216						 guint		text_len);
217GTokenType	g_scanner_get_next_token	(GScanner	*scanner);
218GTokenType	g_scanner_peek_next_token	(GScanner	*scanner);
219GTokenType	g_scanner_cur_token		(GScanner	*scanner);
220GTokenValue	g_scanner_cur_value		(GScanner	*scanner);
221guint		g_scanner_cur_line		(GScanner	*scanner);
222guint		g_scanner_cur_position		(GScanner	*scanner);
223gboolean	g_scanner_eof			(GScanner	*scanner);
224guint		g_scanner_set_scope		(GScanner	*scanner,
225						 guint		 scope_id);
226void		g_scanner_scope_add_symbol	(GScanner	*scanner,
227						 guint		 scope_id,
228						 const gchar	*symbol,
229						 gpointer	value);
230void		g_scanner_scope_remove_symbol	(GScanner	*scanner,
231						 guint		 scope_id,
232						 const gchar	*symbol);
233gpointer	g_scanner_scope_lookup_symbol	(GScanner	*scanner,
234						 guint		 scope_id,
235						 const gchar	*symbol);
236void		g_scanner_scope_foreach_symbol	(GScanner	*scanner,
237						 guint		 scope_id,
238						 GHFunc		 func,
239						 gpointer	 user_data);
240gpointer	g_scanner_lookup_symbol		(GScanner	*scanner,
241						 const gchar	*symbol);
242void		g_scanner_unexp_token		(GScanner	*scanner,
243						 GTokenType	expected_token,
244						 const gchar	*identifier_spec,
245						 const gchar	*symbol_spec,
246						 const gchar	*symbol_name,
247						 const gchar	*message,
248						 gint		 is_error);
249void		g_scanner_error			(GScanner	*scanner,
250						 const gchar	*format,
251						 ...) G_GNUC_PRINTF (2,3);
252void		g_scanner_warn			(GScanner	*scanner,
253						 const gchar	*format,
254						 ...) G_GNUC_PRINTF (2,3);
255
256#ifndef G_DISABLE_DEPRECATED
257
258/* keep downward source compatibility */
259#define		g_scanner_add_symbol( scanner, symbol, value )	G_STMT_START { \
260  g_scanner_scope_add_symbol ((scanner), 0, (symbol), (value)); \
261} G_STMT_END
262#define		g_scanner_remove_symbol( scanner, symbol )	G_STMT_START { \
263  g_scanner_scope_remove_symbol ((scanner), 0, (symbol)); \
264} G_STMT_END
265#define		g_scanner_foreach_symbol( scanner, func, data )	G_STMT_START { \
266  g_scanner_scope_foreach_symbol ((scanner), 0, (func), (data)); \
267} G_STMT_END
268
269/* The following two functions are deprecated and will be removed in
270 * the next major release. They do no good. */
271#define g_scanner_freeze_symbol_table(scanner) ((void)0)
272#define g_scanner_thaw_symbol_table(scanner) ((void)0)
273
274#endif /* G_DISABLE_DEPRECATED */
275
276G_END_DECLS
277
278#endif /* __G_SCANNER_H__ */
279