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, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the GLib Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * GLib at ftp://ftp.gtk.org/pub/gtk/.
23 */
24
25#ifndef __G_SCANNER_H__
26#define __G_SCANNER_H__
27
28#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
29#error "Only <glib.h> can be included directly."
30#endif
31
32#include <glib/gdataset.h>
33#include <glib/ghash.h>
34
35G_BEGIN_DECLS
36
37typedef struct _GScanner GScanner;
38typedef struct _GScannerConfig GScannerConfig;
39typedef union _GTokenValue GTokenValue;
40
41typedef void (*GScannerMsgFunc) (GScanner *scanner,
42 gchar *message,
43 gboolean error);
44
45/* GScanner: Flexible lexical scanner for general purpose.
46 */
47
48/* Character sets */
49#define G_CSET_A_2_Z "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
50#define G_CSET_a_2_z "abcdefghijklmnopqrstuvwxyz"
51#define G_CSET_DIGITS "0123456789"
52#define G_CSET_LATINC "\300\301\302\303\304\305\306"\
53 "\307\310\311\312\313\314\315\316\317\320"\
54 "\321\322\323\324\325\326"\
55 "\330\331\332\333\334\335\336"
56#define G_CSET_LATINS "\337\340\341\342\343\344\345\346"\
57 "\347\350\351\352\353\354\355\356\357\360"\
58 "\361\362\363\364\365\366"\
59 "\370\371\372\373\374\375\376\377"
60
61/* Error types */
62typedef enum
63{
64 G_ERR_UNKNOWN,
65 G_ERR_UNEXP_EOF,
66 G_ERR_UNEXP_EOF_IN_STRING,
67 G_ERR_UNEXP_EOF_IN_COMMENT,
68 G_ERR_NON_DIGIT_IN_CONST,
69 G_ERR_DIGIT_RADIX,
70 G_ERR_FLOAT_RADIX,
71 G_ERR_FLOAT_MALFORMED
72} GErrorType;
73
74/* Token types */
75typedef enum
76{
77 G_TOKEN_EOF = 0,
78
79 G_TOKEN_LEFT_PAREN = '(',
80 G_TOKEN_RIGHT_PAREN = ')',
81 G_TOKEN_LEFT_CURLY = '{',
82 G_TOKEN_RIGHT_CURLY = '}',
83 G_TOKEN_LEFT_BRACE = '[',
84 G_TOKEN_RIGHT_BRACE = ']',
85 G_TOKEN_EQUAL_SIGN = '=',
86 G_TOKEN_COMMA = ',',
87
88 G_TOKEN_NONE = 256,
89
90 G_TOKEN_ERROR,
91
92 G_TOKEN_CHAR,
93 G_TOKEN_BINARY,
94 G_TOKEN_OCTAL,
95 G_TOKEN_INT,
96 G_TOKEN_HEX,
97 G_TOKEN_FLOAT,
98 G_TOKEN_STRING,
99
100 G_TOKEN_SYMBOL,
101 G_TOKEN_IDENTIFIER,
102 G_TOKEN_IDENTIFIER_NULL,
103
104 G_TOKEN_COMMENT_SINGLE,
105 G_TOKEN_COMMENT_MULTI,
106
107 /*< private >*/
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
165 /*< private >*/
166 guint padding_dummy;
167};
168
169struct _GScanner
170{
171 /* unused fields */
172 gpointer user_data;
173 guint max_parse_errors;
174
175 /* g_scanner_error() increments this field */
176 guint parse_errors;
177
178 /* name of input stream, featured by the default message handler */
179 const gchar *input_name;
180
181 /* quarked data */
182 GData *qdata;
183
184 /* link into the scanner configuration */
185 GScannerConfig *config;
186
187 /* fields filled in after g_scanner_get_next_token() */
188 GTokenType token;
189 GTokenValue value;
190 guint line;
191 guint position;
192
193 /* fields filled in after g_scanner_peek_next_token() */
194 GTokenType next_token;
195 GTokenValue next_value;
196 guint next_line;
197 guint next_position;
198
199 /*< private >*/
200 /* to be considered private */
201 GHashTable *symbol_table;
202 gint input_fd;
203 const gchar *text;
204 const gchar *text_end;
205 gchar *buffer;
206 guint scope_id;
207
208 /*< public >*/
209 /* handler function for _warn and _error */
210 GScannerMsgFunc msg_handler;
211};
212
213GLIB_AVAILABLE_IN_ALL
214GScanner* g_scanner_new (const GScannerConfig *config_templ);
215GLIB_AVAILABLE_IN_ALL
216void g_scanner_destroy (GScanner *scanner);
217GLIB_AVAILABLE_IN_ALL
218void g_scanner_input_file (GScanner *scanner,
219 gint input_fd);
220GLIB_AVAILABLE_IN_ALL
221void g_scanner_sync_file_offset (GScanner *scanner);
222GLIB_AVAILABLE_IN_ALL
223void g_scanner_input_text (GScanner *scanner,
224 const gchar *text,
225 guint text_len);
226GLIB_AVAILABLE_IN_ALL
227GTokenType g_scanner_get_next_token (GScanner *scanner);
228GLIB_AVAILABLE_IN_ALL
229GTokenType g_scanner_peek_next_token (GScanner *scanner);
230GLIB_AVAILABLE_IN_ALL
231GTokenType g_scanner_cur_token (GScanner *scanner);
232GLIB_AVAILABLE_IN_ALL
233GTokenValue g_scanner_cur_value (GScanner *scanner);
234GLIB_AVAILABLE_IN_ALL
235guint g_scanner_cur_line (GScanner *scanner);
236GLIB_AVAILABLE_IN_ALL
237guint g_scanner_cur_position (GScanner *scanner);
238GLIB_AVAILABLE_IN_ALL
239gboolean g_scanner_eof (GScanner *scanner);
240GLIB_AVAILABLE_IN_ALL
241guint g_scanner_set_scope (GScanner *scanner,
242 guint scope_id);
243GLIB_AVAILABLE_IN_ALL
244void g_scanner_scope_add_symbol (GScanner *scanner,
245 guint scope_id,
246 const gchar *symbol,
247 gpointer value);
248GLIB_AVAILABLE_IN_ALL
249void g_scanner_scope_remove_symbol (GScanner *scanner,
250 guint scope_id,
251 const gchar *symbol);
252GLIB_AVAILABLE_IN_ALL
253gpointer g_scanner_scope_lookup_symbol (GScanner *scanner,
254 guint scope_id,
255 const gchar *symbol);
256GLIB_AVAILABLE_IN_ALL
257void g_scanner_scope_foreach_symbol (GScanner *scanner,
258 guint scope_id,
259 GHFunc func,
260 gpointer user_data);
261GLIB_AVAILABLE_IN_ALL
262gpointer g_scanner_lookup_symbol (GScanner *scanner,
263 const gchar *symbol);
264GLIB_AVAILABLE_IN_ALL
265void g_scanner_unexp_token (GScanner *scanner,
266 GTokenType expected_token,
267 const gchar *identifier_spec,
268 const gchar *symbol_spec,
269 const gchar *symbol_name,
270 const gchar *message,
271 gint is_error);
272GLIB_AVAILABLE_IN_ALL
273void g_scanner_error (GScanner *scanner,
274 const gchar *format,
275 ...) G_GNUC_PRINTF (2,3);
276GLIB_AVAILABLE_IN_ALL
277void g_scanner_warn (GScanner *scanner,
278 const gchar *format,
279 ...) G_GNUC_PRINTF (2,3);
280
281#ifndef G_DISABLE_DEPRECATED
282
283/* keep downward source compatibility */
284#define g_scanner_add_symbol( scanner, symbol, value ) G_STMT_START { \
285 g_scanner_scope_add_symbol ((scanner), 0, (symbol), (value)); \
286} G_STMT_END
287#define g_scanner_remove_symbol( scanner, symbol ) G_STMT_START { \
288 g_scanner_scope_remove_symbol ((scanner), 0, (symbol)); \
289} G_STMT_END
290#define g_scanner_foreach_symbol( scanner, func, data ) G_STMT_START { \
291 g_scanner_scope_foreach_symbol ((scanner), 0, (func), (data)); \
292} G_STMT_END
293
294/* The following two functions are deprecated and will be removed in
295 * the next major release. They do no good. */
296#define g_scanner_freeze_symbol_table(scanner) ((void)0)
297#define g_scanner_thaw_symbol_table(scanner) ((void)0)
298
299#endif /* G_DISABLE_DEPRECATED */
300
301G_END_DECLS
302
303#endif /* __G_SCANNER_H__ */
304