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.1 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 35 G_BEGIN_DECLS 36 37 typedef struct _GScanner GScanner; 38 typedef struct _GScannerConfig GScannerConfig; 39 typedef union _GTokenValue GTokenValue; 40 41 typedef 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 */ 62 typedef 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 */ 75 typedef 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 111 union _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 127 struct _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 169 struct _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 213 GLIB_AVAILABLE_IN_ALL 214 GScanner* g_scanner_new (const GScannerConfig *config_templ); 215 GLIB_AVAILABLE_IN_ALL 216 void g_scanner_destroy (GScanner *scanner); 217 GLIB_AVAILABLE_IN_ALL 218 void g_scanner_input_file (GScanner *scanner, 219 gint input_fd); 220 GLIB_AVAILABLE_IN_ALL 221 void g_scanner_sync_file_offset (GScanner *scanner); 222 GLIB_AVAILABLE_IN_ALL 223 void g_scanner_input_text (GScanner *scanner, 224 const gchar *text, 225 guint text_len); 226 GLIB_AVAILABLE_IN_ALL 227 GTokenType g_scanner_get_next_token (GScanner *scanner); 228 GLIB_AVAILABLE_IN_ALL 229 GTokenType g_scanner_peek_next_token (GScanner *scanner); 230 GLIB_AVAILABLE_IN_ALL 231 GTokenType g_scanner_cur_token (GScanner *scanner); 232 GLIB_AVAILABLE_IN_ALL 233 GTokenValue g_scanner_cur_value (GScanner *scanner); 234 GLIB_AVAILABLE_IN_ALL 235 guint g_scanner_cur_line (GScanner *scanner); 236 GLIB_AVAILABLE_IN_ALL 237 guint g_scanner_cur_position (GScanner *scanner); 238 GLIB_AVAILABLE_IN_ALL 239 gboolean g_scanner_eof (GScanner *scanner); 240 GLIB_AVAILABLE_IN_ALL 241 guint g_scanner_set_scope (GScanner *scanner, 242 guint scope_id); 243 GLIB_AVAILABLE_IN_ALL 244 void g_scanner_scope_add_symbol (GScanner *scanner, 245 guint scope_id, 246 const gchar *symbol, 247 gpointer value); 248 GLIB_AVAILABLE_IN_ALL 249 void g_scanner_scope_remove_symbol (GScanner *scanner, 250 guint scope_id, 251 const gchar *symbol); 252 GLIB_AVAILABLE_IN_ALL 253 gpointer g_scanner_scope_lookup_symbol (GScanner *scanner, 254 guint scope_id, 255 const gchar *symbol); 256 GLIB_AVAILABLE_IN_ALL 257 void g_scanner_scope_foreach_symbol (GScanner *scanner, 258 guint scope_id, 259 GHFunc func, 260 gpointer user_data); 261 GLIB_AVAILABLE_IN_ALL 262 gpointer g_scanner_lookup_symbol (GScanner *scanner, 263 const gchar *symbol); 264 GLIB_AVAILABLE_IN_ALL 265 void 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); 272 GLIB_AVAILABLE_IN_ALL 273 void g_scanner_error (GScanner *scanner, 274 const gchar *format, 275 ...) G_GNUC_PRINTF (2,3); 276 GLIB_AVAILABLE_IN_ALL 277 void g_scanner_warn (GScanner *scanner, 278 const gchar *format, 279 ...) G_GNUC_PRINTF (2,3); 280 281 /* keep downward source compatibility */ 282 #define g_scanner_add_symbol( scanner, symbol, value ) G_STMT_START { \ 283 g_scanner_scope_add_symbol ((scanner), 0, (symbol), (value)); \ 284 } G_STMT_END GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_scanner_scope_add_symbol) 285 #define g_scanner_remove_symbol( scanner, symbol ) G_STMT_START { \ 286 g_scanner_scope_remove_symbol ((scanner), 0, (symbol)); \ 287 } G_STMT_END GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_scanner_scope_remove_symbol) 288 #define g_scanner_foreach_symbol( scanner, func, data ) G_STMT_START { \ 289 g_scanner_scope_foreach_symbol ((scanner), 0, (func), (data)); \ 290 } G_STMT_END GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_scanner_scope_foreach_symbol) 291 292 /* The following two functions are deprecated and will be removed in 293 * the next major release. They do no good. */ 294 #define g_scanner_freeze_symbol_table(scanner) ((void)0) GLIB_DEPRECATED_MACRO_IN_2_26 295 #define g_scanner_thaw_symbol_table(scanner) ((void)0) GLIB_DEPRECATED_MACRO_IN_2_26 296 297 G_END_DECLS 298 299 #endif /* __G_SCANNER_H__ */ 300