From b813e192c6aac15a7884b398617c208fe6d548de Mon Sep 17 00:00:00 2001 From: Tim Janik Date: Wed, 22 Jul 1998 22:32:22 +0000 Subject: [PATCH] new functions to make a scanner scope sensitive wrt symbol lookups. Thu Jul 23 00:29:14 1998 Tim Janik * glib.h: * gscanner.c: new functions to make a scanner scope sensitive wrt symbol lookups. g_scanner_scope_foreach_symbol, g_scanner_scope_lookup_symbol, g_scanner_scope_remove_symbol, g_scanner_scope_add_symbol and g_scanner_set_scope. g_scanner_add_symbol, g_scanner_remove_symbol and g_scanner_foreach_symbol are now aliases for scope 0. --- ChangeLog | 11 ++ ChangeLog.pre-2-0 | 11 ++ ChangeLog.pre-2-10 | 11 ++ ChangeLog.pre-2-12 | 11 ++ ChangeLog.pre-2-2 | 11 ++ ChangeLog.pre-2-4 | 11 ++ ChangeLog.pre-2-6 | 11 ++ ChangeLog.pre-2-8 | 11 ++ glib.h | 41 ++++-- glib/glib.h | 41 ++++-- glib/gscanner.c | 359 ++++++++++++++++++++++++++++++++++------------------- glibconfig.h.in | 6 +- gscanner.c | 359 ++++++++++++++++++++++++++++++++++------------------- 13 files changed, 617 insertions(+), 277 deletions(-) diff --git a/ChangeLog b/ChangeLog index 32c84a3..ee5bd8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Thu Jul 23 00:29:14 1998 Tim Janik + + * glib.h: + * gscanner.c: new functions to make a scanner scope sensitive wrt + symbol lookups. + g_scanner_scope_foreach_symbol, g_scanner_scope_lookup_symbol, + g_scanner_scope_remove_symbol, g_scanner_scope_add_symbol and + g_scanner_set_scope. + g_scanner_add_symbol, g_scanner_remove_symbol and + g_scanner_foreach_symbol are now aliases for scope 0. + Mon Jul 20 23:05:34 1998 George Lebl * glib.h: typo fixed for alphas for gint64 diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 32c84a3..ee5bd8e 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,14 @@ +Thu Jul 23 00:29:14 1998 Tim Janik + + * glib.h: + * gscanner.c: new functions to make a scanner scope sensitive wrt + symbol lookups. + g_scanner_scope_foreach_symbol, g_scanner_scope_lookup_symbol, + g_scanner_scope_remove_symbol, g_scanner_scope_add_symbol and + g_scanner_set_scope. + g_scanner_add_symbol, g_scanner_remove_symbol and + g_scanner_foreach_symbol are now aliases for scope 0. + Mon Jul 20 23:05:34 1998 George Lebl * glib.h: typo fixed for alphas for gint64 diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 32c84a3..ee5bd8e 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,14 @@ +Thu Jul 23 00:29:14 1998 Tim Janik + + * glib.h: + * gscanner.c: new functions to make a scanner scope sensitive wrt + symbol lookups. + g_scanner_scope_foreach_symbol, g_scanner_scope_lookup_symbol, + g_scanner_scope_remove_symbol, g_scanner_scope_add_symbol and + g_scanner_set_scope. + g_scanner_add_symbol, g_scanner_remove_symbol and + g_scanner_foreach_symbol are now aliases for scope 0. + Mon Jul 20 23:05:34 1998 George Lebl * glib.h: typo fixed for alphas for gint64 diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 32c84a3..ee5bd8e 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,14 @@ +Thu Jul 23 00:29:14 1998 Tim Janik + + * glib.h: + * gscanner.c: new functions to make a scanner scope sensitive wrt + symbol lookups. + g_scanner_scope_foreach_symbol, g_scanner_scope_lookup_symbol, + g_scanner_scope_remove_symbol, g_scanner_scope_add_symbol and + g_scanner_set_scope. + g_scanner_add_symbol, g_scanner_remove_symbol and + g_scanner_foreach_symbol are now aliases for scope 0. + Mon Jul 20 23:05:34 1998 George Lebl * glib.h: typo fixed for alphas for gint64 diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 32c84a3..ee5bd8e 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,14 @@ +Thu Jul 23 00:29:14 1998 Tim Janik + + * glib.h: + * gscanner.c: new functions to make a scanner scope sensitive wrt + symbol lookups. + g_scanner_scope_foreach_symbol, g_scanner_scope_lookup_symbol, + g_scanner_scope_remove_symbol, g_scanner_scope_add_symbol and + g_scanner_set_scope. + g_scanner_add_symbol, g_scanner_remove_symbol and + g_scanner_foreach_symbol are now aliases for scope 0. + Mon Jul 20 23:05:34 1998 George Lebl * glib.h: typo fixed for alphas for gint64 diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 32c84a3..ee5bd8e 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,14 @@ +Thu Jul 23 00:29:14 1998 Tim Janik + + * glib.h: + * gscanner.c: new functions to make a scanner scope sensitive wrt + symbol lookups. + g_scanner_scope_foreach_symbol, g_scanner_scope_lookup_symbol, + g_scanner_scope_remove_symbol, g_scanner_scope_add_symbol and + g_scanner_set_scope. + g_scanner_add_symbol, g_scanner_remove_symbol and + g_scanner_foreach_symbol are now aliases for scope 0. + Mon Jul 20 23:05:34 1998 George Lebl * glib.h: typo fixed for alphas for gint64 diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 32c84a3..ee5bd8e 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,14 @@ +Thu Jul 23 00:29:14 1998 Tim Janik + + * glib.h: + * gscanner.c: new functions to make a scanner scope sensitive wrt + symbol lookups. + g_scanner_scope_foreach_symbol, g_scanner_scope_lookup_symbol, + g_scanner_scope_remove_symbol, g_scanner_scope_add_symbol and + g_scanner_set_scope. + g_scanner_add_symbol, g_scanner_remove_symbol and + g_scanner_foreach_symbol are now aliases for scope 0. + Mon Jul 20 23:05:34 1998 George Lebl * glib.h: typo fixed for alphas for gint64 diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 32c84a3..ee5bd8e 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,14 @@ +Thu Jul 23 00:29:14 1998 Tim Janik + + * glib.h: + * gscanner.c: new functions to make a scanner scope sensitive wrt + symbol lookups. + g_scanner_scope_foreach_symbol, g_scanner_scope_lookup_symbol, + g_scanner_scope_remove_symbol, g_scanner_scope_add_symbol and + g_scanner_set_scope. + g_scanner_add_symbol, g_scanner_remove_symbol and + g_scanner_foreach_symbol are now aliases for scope 0. + Mon Jul 20 23:05:34 1998 George Lebl * glib.h: typo fixed for alphas for gint64 diff --git a/glib.h b/glib.h index a0333d2..4c17790 100644 --- a/glib.h +++ b/glib.h @@ -8,7 +8,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -447,9 +447,9 @@ typedef unsigned long long guint64; /* This should never happen */ #endif -typedef gint32 gssize; +typedef gint32 gssize; typedef guint32 gsize; -typedef gint32 gtime; +typedef gint32 gtime; typedef guint32 GQuark; typedef struct _GList GList; @@ -526,13 +526,13 @@ struct _GArray struct _GByteArray { guint8 *data; - guint len; + guint len; }; struct _GPtrArray { gpointer *pdata; - guint len; + guint len; }; struct _GTuples @@ -543,7 +543,7 @@ struct _GTuples struct _GDebugKey { gchar *key; - guint value; + guint value; }; struct _GCache { gint dummy; }; @@ -1155,6 +1155,7 @@ struct _GScannerConfig guint identifier_2_string : 1; guint char_2_token : 1; /* return G_TOKEN_CHAR? */ guint symbol_2_token : 1; + guint scope_0_fallback : 1; /* try scope 0 on lookups? */ }; struct _GScanner @@ -1193,6 +1194,7 @@ struct _GScanner guint text_len; gint input_fd; gint peeked_char; + guint scope_id; /* handler function for _warn and _error */ GScannerMsgFunc msg_handler; @@ -1212,15 +1214,23 @@ GValue g_scanner_cur_value (GScanner *scanner); guint g_scanner_cur_line (GScanner *scanner); guint g_scanner_cur_position (GScanner *scanner); gboolean g_scanner_eof (GScanner *scanner); -void g_scanner_add_symbol (GScanner *scanner, +guint g_scanner_set_scope (GScanner *scanner, + guint scope_id); +void g_scanner_scope_add_symbol (GScanner *scanner, + guint scope_id, const gchar *symbol, gpointer value); -gpointer g_scanner_lookup_symbol (GScanner *scanner, +void g_scanner_scope_remove_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol); +gpointer g_scanner_scope_lookup_symbol (GScanner *scanner, + guint scope_id, const gchar *symbol); -void g_scanner_foreach_symbol (GScanner *scanner, +void g_scanner_scope_foreach_symbol (GScanner *scanner, + guint scope_id, GHFunc func, gpointer func_data); -void g_scanner_remove_symbol (GScanner *scanner, +gpointer g_scanner_lookup_symbol (GScanner *scanner, const gchar *symbol); void g_scanner_freeze_symbol_table (GScanner *scanner); void g_scanner_thaw_symbol_table (GScanner *scanner); @@ -1238,6 +1248,17 @@ void g_scanner_warn (GScanner *scanner, const gchar *format, ...) G_GNUC_PRINTF (2,3); gint g_scanner_stat_mode (const gchar *filename); +/* keep downward source compatibility */ +#define g_scanner_add_symbol( scanner, symbol, value ) G_STMT_START { \ + g_scanner_scope_add_symbol ((scanner), 0, (symbol), (value)); \ +} G_STMT_END +#define g_scanner_remove_symbol( scanner, symbol ) G_STMT_START { \ + g_scanner_scope_remove_symbol ((scanner), 0, (symbol)); \ +} G_STMT_END +#define g_scanner_foreach_symbol( scanner, func, data ) G_STMT_START { \ + g_scanner_scope_foreach_symbol ((scanner), 0, (func), (data)); \ +} G_STMT_END + /* Completion */ diff --git a/glib/glib.h b/glib/glib.h index a0333d2..4c17790 100644 --- a/glib/glib.h +++ b/glib/glib.h @@ -8,7 +8,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -447,9 +447,9 @@ typedef unsigned long long guint64; /* This should never happen */ #endif -typedef gint32 gssize; +typedef gint32 gssize; typedef guint32 gsize; -typedef gint32 gtime; +typedef gint32 gtime; typedef guint32 GQuark; typedef struct _GList GList; @@ -526,13 +526,13 @@ struct _GArray struct _GByteArray { guint8 *data; - guint len; + guint len; }; struct _GPtrArray { gpointer *pdata; - guint len; + guint len; }; struct _GTuples @@ -543,7 +543,7 @@ struct _GTuples struct _GDebugKey { gchar *key; - guint value; + guint value; }; struct _GCache { gint dummy; }; @@ -1155,6 +1155,7 @@ struct _GScannerConfig guint identifier_2_string : 1; guint char_2_token : 1; /* return G_TOKEN_CHAR? */ guint symbol_2_token : 1; + guint scope_0_fallback : 1; /* try scope 0 on lookups? */ }; struct _GScanner @@ -1193,6 +1194,7 @@ struct _GScanner guint text_len; gint input_fd; gint peeked_char; + guint scope_id; /* handler function for _warn and _error */ GScannerMsgFunc msg_handler; @@ -1212,15 +1214,23 @@ GValue g_scanner_cur_value (GScanner *scanner); guint g_scanner_cur_line (GScanner *scanner); guint g_scanner_cur_position (GScanner *scanner); gboolean g_scanner_eof (GScanner *scanner); -void g_scanner_add_symbol (GScanner *scanner, +guint g_scanner_set_scope (GScanner *scanner, + guint scope_id); +void g_scanner_scope_add_symbol (GScanner *scanner, + guint scope_id, const gchar *symbol, gpointer value); -gpointer g_scanner_lookup_symbol (GScanner *scanner, +void g_scanner_scope_remove_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol); +gpointer g_scanner_scope_lookup_symbol (GScanner *scanner, + guint scope_id, const gchar *symbol); -void g_scanner_foreach_symbol (GScanner *scanner, +void g_scanner_scope_foreach_symbol (GScanner *scanner, + guint scope_id, GHFunc func, gpointer func_data); -void g_scanner_remove_symbol (GScanner *scanner, +gpointer g_scanner_lookup_symbol (GScanner *scanner, const gchar *symbol); void g_scanner_freeze_symbol_table (GScanner *scanner); void g_scanner_thaw_symbol_table (GScanner *scanner); @@ -1238,6 +1248,17 @@ void g_scanner_warn (GScanner *scanner, const gchar *format, ...) G_GNUC_PRINTF (2,3); gint g_scanner_stat_mode (const gchar *filename); +/* keep downward source compatibility */ +#define g_scanner_add_symbol( scanner, symbol, value ) G_STMT_START { \ + g_scanner_scope_add_symbol ((scanner), 0, (symbol), (value)); \ +} G_STMT_END +#define g_scanner_remove_symbol( scanner, symbol ) G_STMT_START { \ + g_scanner_scope_remove_symbol ((scanner), 0, (symbol)); \ +} G_STMT_END +#define g_scanner_foreach_symbol( scanner, func, data ) G_STMT_START { \ + g_scanner_scope_foreach_symbol ((scanner), 0, (func), (data)); \ +} G_STMT_END + /* Completion */ diff --git a/glib/gscanner.c b/glib/gscanner.c index d401c91..cb4bf59 100644 --- a/glib/gscanner.c +++ b/glib/gscanner.c @@ -45,12 +45,13 @@ /* --- typedefs --- */ -typedef struct _GScannerHashVal GScannerHashVal; +typedef struct _GScannerKey GScannerKey; -struct _GScannerHashVal +struct _GScannerKey { - gchar *key; - gpointer value; + guint scope_id; + gchar *symbol; + gpointer value; }; @@ -96,36 +97,42 @@ static GScannerConfig g_scanner_config_template = FALSE /* identifier_2_string */, TRUE /* char_2_token */, FALSE /* symbol_2_token */, + FALSE /* scope_0_fallback */, }; /* --- prototypes --- */ extern char* g_vsprintf (gchar *fmt, va_list *args, va_list *args2); -static GScannerHashVal* g_scanner_lookup_internal (GScanner *scanner, - const gchar *symbol); -static void g_scanner_get_token_ll (GScanner *scanner, - GTokenType *token_p, - GValue *value_p, - guint *line_p, - guint *position_p); -static void g_scanner_get_token_i (GScanner *scanner, - GTokenType *token_p, - GValue *value_p, - guint *line_p, - guint *position_p); -static void g_scanner_free_value (GTokenType *token_p, - GValue *value_p); - -static inline -gint g_scanner_char_2_num (guchar c, - guchar base); -static guchar g_scanner_peek_next_char(GScanner *scanner); -static guchar g_scanner_get_char (GScanner *scanner, - guint *line_p, - guint *position_p); -static void g_scanner_msg_handler (GScanner *scanner, - gchar *message, - gint is_error); +static inline +gint g_scanner_char_2_num (guchar c, + guchar base); +static inline +GScannerKey* g_scanner_lookup_internal (GScanner *scanner, + guint scope_id, + const gchar *symbol); +static gint g_scanner_key_equal (gconstpointer v1, + gconstpointer v2); +static guint g_scanner_key_hash (gconstpointer v); +static void g_scanner_get_token_ll (GScanner *scanner, + GTokenType *token_p, + GValue *value_p, + guint *line_p, + guint *position_p); +static void g_scanner_get_token_i (GScanner *scanner, + GTokenType *token_p, + GValue *value_p, + guint *line_p, + guint *position_p); +static void g_scanner_free_value (GTokenType *token_p, + GValue *value_p); + +static guchar g_scanner_peek_next_char (GScanner *scanner); +static guchar g_scanner_get_char (GScanner *scanner, + guint *line_p, + guint *position_p); +static void g_scanner_msg_handler (GScanner *scanner, + gchar *message, + gint is_error); /* --- functions --- */ @@ -190,6 +197,7 @@ g_scanner_new (GScannerConfig *config_templ) scanner->config->identifier_2_string = config_templ->identifier_2_string; scanner->config->char_2_token = config_templ->char_2_token; scanner->config->symbol_2_token = config_templ->symbol_2_token; + scanner->config->scope_0_fallback = config_templ->scope_0_fallback; scanner->token = G_TOKEN_NONE; scanner->value.v_int = 0; @@ -201,11 +209,12 @@ g_scanner_new (GScannerConfig *config_templ) scanner->next_line = 1; scanner->next_position = 0; - scanner->symbol_table = g_hash_table_new (g_str_hash, g_str_equal); + scanner->symbol_table = g_hash_table_new (g_scanner_key_hash, g_scanner_key_equal); scanner->text = NULL; scanner->text_len = 0; scanner->input_fd = -1; scanner->peeked_char = -1; + scanner->scope_id = 0; scanner->msg_handler = g_scanner_msg_handler; @@ -213,12 +222,14 @@ g_scanner_new (GScannerConfig *config_templ) } static void -g_scanner_destroy_symbol_table_entry (gpointer key, - gpointer value, - gpointer user_data) +g_scanner_destroy_symbol_table_entry (gpointer _key, + gpointer _value, + gpointer _data) { + GScannerKey *key = _key; + + g_free (key->symbol); g_free (key); - g_free (value); } void @@ -227,7 +238,7 @@ g_scanner_destroy (GScanner *scanner) g_return_if_fail (scanner != NULL); g_hash_table_foreach (scanner->symbol_table, - g_scanner_destroy_symbol_table_entry, NULL); + g_scanner_destroy_symbol_table_entry, NULL); g_hash_table_destroy (scanner->symbol_table); g_scanner_free_value (&scanner->token, &scanner->value); g_scanner_free_value (&scanner->next_token, &scanner->next_value); @@ -236,7 +247,7 @@ g_scanner_destroy (GScanner *scanner) } static void -g_scanner_msg_handler (GScanner *scanner, +g_scanner_msg_handler (GScanner *scanner, gchar *message, gint is_error) { @@ -249,8 +260,8 @@ g_scanner_msg_handler (GScanner *scanner, } void -g_scanner_error (GScanner *scanner, - const gchar *format, +g_scanner_error (GScanner *scanner, + const gchar *format, ...) { g_return_if_fail (scanner != NULL); @@ -341,108 +352,223 @@ g_scanner_input_text (GScanner *scanner, scanner->peeked_char = -1; } +static gint +g_scanner_key_equal (gconstpointer v1, + gconstpointer v2) +{ + register const GScannerKey *key1 = v1; + register const GScannerKey *key2 = v2; + + return (key1->scope_id == key2->scope_id) && (strcmp (key1->symbol, key2->symbol) == 0); +} + +static guint +g_scanner_key_hash (gconstpointer v) +{ + register const GScannerKey *key = v; + register gchar *c; + register guint h; + + h = key->scope_id; + for (c = key->symbol; *c; c++) + { + register guint g; + + h = (h << 4) + *c; + g = h & 0xf0000000; + if (g) + { + h = h ^ (g >> 24); + h = h ^ g; + } + } + + return h; +} + +static inline GScannerKey* +g_scanner_lookup_internal (GScanner *scanner, + guint scope_id, + const gchar *symbol) +{ + register GScannerKey *key_p; + GScannerKey key; + + key.scope_id = scope_id; + + if (!scanner->config->case_sensitive) + { + register gchar *d; + register const gchar *c; + + key.symbol = g_new (gchar, strlen (symbol) + 1); + for (d = key.symbol, c = symbol; *c; c++, d++) + *d = to_lower (*c); + *d = 0; + key_p = g_hash_table_lookup (scanner->symbol_table, &key); + g_free (key.symbol); + } + else + { + key.symbol = (gchar*) symbol; + key_p = g_hash_table_lookup (scanner->symbol_table, &key); + } + + return key_p; +} + void -g_scanner_add_symbol (GScanner *scanner, - const gchar *symbol, - gpointer value) +g_scanner_scope_add_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol, + gpointer value) { - register GScannerHashVal *hash_val; + register GScannerKey *key; g_return_if_fail (scanner != NULL); g_return_if_fail (symbol != NULL); - hash_val = g_scanner_lookup_internal (scanner, symbol); + key = g_scanner_lookup_internal (scanner, scope_id, symbol); - if (!hash_val) + if (!key) { - hash_val = g_new (GScannerHashVal, 1); - hash_val->key = g_strdup (symbol); - hash_val->value = value; + key = g_new (GScannerKey, 1); + key->scope_id = scope_id; + key->symbol = g_strdup (symbol); + key->value = value; if (!scanner->config->case_sensitive) { - register guint i, l; - - l = strlen (hash_val->key); - for (i = 0; i < l; i++) - hash_val->key[i] = to_lower (hash_val->key[i]); + register gchar *c; + + c = key->symbol; + while (*c != 0) + { + *c = to_lower (*c); + c++; + } } - g_hash_table_insert (scanner->symbol_table, hash_val->key, hash_val); + g_hash_table_insert (scanner->symbol_table, key, key); } else - hash_val->value = value; + key->value = value; +} + +void +g_scanner_scope_remove_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol) +{ + register GScannerKey *key; + + g_return_if_fail (scanner != NULL); + g_return_if_fail (symbol != NULL); + + key = g_scanner_lookup_internal (scanner, scope_id, symbol); + + if (key) + { + g_hash_table_remove (scanner->symbol_table, key); + g_free (key->symbol); + g_free (key); + } } gpointer g_scanner_lookup_symbol (GScanner *scanner, const gchar *symbol) { - register GScannerHashVal *hash_val; + register GScannerKey *key; + register guint scope_id; + + g_return_val_if_fail (scanner != NULL, NULL); + + if (!symbol) + return NULL; + + scope_id = scanner->scope_id; + key = g_scanner_lookup_internal (scanner, scope_id, symbol); + if (!key && scope_id && scanner->config->scope_0_fallback) + key = g_scanner_lookup_internal (scanner, 0, symbol); + + if (key) + return key->value; + else + return NULL; +} + +gpointer +g_scanner_scope_lookup_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol) +{ + register GScannerKey *key; g_return_val_if_fail (scanner != NULL, NULL); if (!symbol) return NULL; - hash_val = g_scanner_lookup_internal (scanner, symbol); + key = g_scanner_lookup_internal (scanner, scope_id, symbol); - if (hash_val) - return hash_val->value; + if (key) + return key->value; else return NULL; } +guint +g_scanner_set_scope (GScanner *scanner, + guint scope_id) +{ + register guint old_scope_id; + + g_return_val_if_fail (scanner != NULL, 0); + + old_scope_id = scanner->scope_id; + scanner->scope_id = scope_id; + + return old_scope_id; +} + static void -g_scanner_foreach_internal (gpointer key, - gpointer value, - gpointer user_data) +g_scanner_foreach_internal (gpointer _key, + gpointer _value, + gpointer _user_data) { - register GScannerHashVal *hash_val; + register GScannerKey *key; + register gpointer *d; register GHFunc func; register gpointer func_data; - register gpointer *d; + register guint *scope_id; - d = user_data; - func = (GHFunc)d[0]; + d = _user_data; + func = (GHFunc) d[0]; func_data = d[1]; - hash_val = value; + scope_id = d[2]; + key = _value; - func (key, hash_val->value, func_data); + if (key->scope_id == *scope_id) + func (key->symbol, key->value, func_data); } void -g_scanner_foreach_symbol (GScanner *scanner, - GHFunc func, - gpointer func_data) +g_scanner_scope_foreach_symbol (GScanner *scanner, + guint scope_id, + GHFunc func, + gpointer func_data) { - gpointer d[2]; + gpointer d[3]; g_return_if_fail (scanner != NULL); - d[0] = (gpointer)func; + d[0] = (gpointer) func; d[1] = func_data; + d[2] = &scope_id; g_hash_table_foreach (scanner->symbol_table, g_scanner_foreach_internal, d); } void -g_scanner_remove_symbol (GScanner *scanner, - const gchar *symbol) -{ - register GScannerHashVal *hash_val; - - g_return_if_fail (scanner != NULL); - - hash_val = g_scanner_lookup_internal (scanner, symbol); - - if (hash_val) - { - g_hash_table_remove (scanner->symbol_table, hash_val->key); - g_free (hash_val->key); - g_free (hash_val); - } -} - -void g_scanner_freeze_symbol_table (GScanner *scanner) { g_return_if_fail (scanner != NULL); @@ -545,31 +671,6 @@ g_scanner_eof (GScanner *scanner) return scanner->token == G_TOKEN_EOF; } -static GScannerHashVal* -g_scanner_lookup_internal (GScanner *scanner, - const gchar *symbol) -{ - register GScannerHashVal *hash_val; - - if (!scanner->config->case_sensitive) - { - register gchar *buffer; - register guint i, l; - - l = strlen (symbol); - buffer = g_new (gchar, l + 1); - for (i = 0; i < l; i++) - buffer[i] = to_lower (symbol[i]); - buffer[i] = 0; - hash_val = g_hash_table_lookup (scanner->symbol_table, buffer); - g_free (buffer); - } - else - hash_val = g_hash_table_lookup (scanner->symbol_table, (gchar*) symbol); - - return hash_val; -} - static guchar g_scanner_peek_next_char (GScanner *scanner) { @@ -676,7 +777,7 @@ g_scanner_unexp_token (GScanner *scanner, register guint expected_string_len; register gchar *message_prefix; register gboolean print_unexp; - void (*msg_handler) (GScanner*, const gchar*, ...); + void (*msg_handler) (GScanner*, const gchar*, ...); g_return_if_fail (scanner != NULL); @@ -944,7 +1045,7 @@ gint g_scanner_stat_mode (const gchar *filename) { struct stat *stat_buf; - gint st_mode; + gint st_mode; stat_buf = g_new0 (struct stat, 1); @@ -1001,19 +1102,19 @@ g_scanner_get_token_i (GScanner *scanner, switch (*token_p) { - case G_TOKEN_IDENTIFIER: + case G_TOKEN_IDENTIFIER: if (scanner->config->identifier_2_string) *token_p = G_TOKEN_STRING; break; - case G_TOKEN_SYMBOL: + case G_TOKEN_SYMBOL: if (scanner->config->symbol_2_token) *token_p = (GTokenType) value_p->v_symbol; break; - case G_TOKEN_BINARY: - case G_TOKEN_OCTAL: - case G_TOKEN_HEX: + case G_TOKEN_BINARY: + case G_TOKEN_OCTAL: + case G_TOKEN_HEX: if (scanner->config->numbers_2_int) *token_p = G_TOKEN_INT; break; @@ -1531,15 +1632,19 @@ g_scanner_get_token_ll (GScanner *scanner, if (token == G_TOKEN_IDENTIFIER && config->scan_symbols) { - register GScannerHashVal *hash_val; - - hash_val = g_scanner_lookup_internal (scanner, value.v_identifier); + register GScannerKey *key; + register guint scope_id; + + scope_id = scanner->scope_id; + key = g_scanner_lookup_internal (scanner, scope_id, value.v_identifier); + if (!key && scope_id && scanner->config->scope_0_fallback) + key = g_scanner_lookup_internal (scanner, 0, value.v_identifier); - if (hash_val) + if (key) { g_free (value.v_identifier); token = G_TOKEN_SYMBOL; - value.v_symbol = hash_val->value; + value.v_symbol = key->value; } } diff --git a/glibconfig.h.in b/glibconfig.h.in index ca9c62c..e622275 100644 --- a/glibconfig.h.in +++ b/glibconfig.h.in @@ -50,15 +50,15 @@ /* The number of bytes in a long. */ #undef SIZEOF_LONG +/* The number of bytes in a long long. */ +#undef SIZEOF_LONG_LONG + /* The number of bytes in a short. */ #undef SIZEOF_SHORT /* The number of bytes in a void *. */ #undef SIZEOF_VOID_P -/* The number of bytes in a long long. */ -#undef SIZEOF_LONG_LONG - /* Define if you have the atexit function. */ #undef HAVE_ATEXIT diff --git a/gscanner.c b/gscanner.c index d401c91..cb4bf59 100644 --- a/gscanner.c +++ b/gscanner.c @@ -45,12 +45,13 @@ /* --- typedefs --- */ -typedef struct _GScannerHashVal GScannerHashVal; +typedef struct _GScannerKey GScannerKey; -struct _GScannerHashVal +struct _GScannerKey { - gchar *key; - gpointer value; + guint scope_id; + gchar *symbol; + gpointer value; }; @@ -96,36 +97,42 @@ static GScannerConfig g_scanner_config_template = FALSE /* identifier_2_string */, TRUE /* char_2_token */, FALSE /* symbol_2_token */, + FALSE /* scope_0_fallback */, }; /* --- prototypes --- */ extern char* g_vsprintf (gchar *fmt, va_list *args, va_list *args2); -static GScannerHashVal* g_scanner_lookup_internal (GScanner *scanner, - const gchar *symbol); -static void g_scanner_get_token_ll (GScanner *scanner, - GTokenType *token_p, - GValue *value_p, - guint *line_p, - guint *position_p); -static void g_scanner_get_token_i (GScanner *scanner, - GTokenType *token_p, - GValue *value_p, - guint *line_p, - guint *position_p); -static void g_scanner_free_value (GTokenType *token_p, - GValue *value_p); - -static inline -gint g_scanner_char_2_num (guchar c, - guchar base); -static guchar g_scanner_peek_next_char(GScanner *scanner); -static guchar g_scanner_get_char (GScanner *scanner, - guint *line_p, - guint *position_p); -static void g_scanner_msg_handler (GScanner *scanner, - gchar *message, - gint is_error); +static inline +gint g_scanner_char_2_num (guchar c, + guchar base); +static inline +GScannerKey* g_scanner_lookup_internal (GScanner *scanner, + guint scope_id, + const gchar *symbol); +static gint g_scanner_key_equal (gconstpointer v1, + gconstpointer v2); +static guint g_scanner_key_hash (gconstpointer v); +static void g_scanner_get_token_ll (GScanner *scanner, + GTokenType *token_p, + GValue *value_p, + guint *line_p, + guint *position_p); +static void g_scanner_get_token_i (GScanner *scanner, + GTokenType *token_p, + GValue *value_p, + guint *line_p, + guint *position_p); +static void g_scanner_free_value (GTokenType *token_p, + GValue *value_p); + +static guchar g_scanner_peek_next_char (GScanner *scanner); +static guchar g_scanner_get_char (GScanner *scanner, + guint *line_p, + guint *position_p); +static void g_scanner_msg_handler (GScanner *scanner, + gchar *message, + gint is_error); /* --- functions --- */ @@ -190,6 +197,7 @@ g_scanner_new (GScannerConfig *config_templ) scanner->config->identifier_2_string = config_templ->identifier_2_string; scanner->config->char_2_token = config_templ->char_2_token; scanner->config->symbol_2_token = config_templ->symbol_2_token; + scanner->config->scope_0_fallback = config_templ->scope_0_fallback; scanner->token = G_TOKEN_NONE; scanner->value.v_int = 0; @@ -201,11 +209,12 @@ g_scanner_new (GScannerConfig *config_templ) scanner->next_line = 1; scanner->next_position = 0; - scanner->symbol_table = g_hash_table_new (g_str_hash, g_str_equal); + scanner->symbol_table = g_hash_table_new (g_scanner_key_hash, g_scanner_key_equal); scanner->text = NULL; scanner->text_len = 0; scanner->input_fd = -1; scanner->peeked_char = -1; + scanner->scope_id = 0; scanner->msg_handler = g_scanner_msg_handler; @@ -213,12 +222,14 @@ g_scanner_new (GScannerConfig *config_templ) } static void -g_scanner_destroy_symbol_table_entry (gpointer key, - gpointer value, - gpointer user_data) +g_scanner_destroy_symbol_table_entry (gpointer _key, + gpointer _value, + gpointer _data) { + GScannerKey *key = _key; + + g_free (key->symbol); g_free (key); - g_free (value); } void @@ -227,7 +238,7 @@ g_scanner_destroy (GScanner *scanner) g_return_if_fail (scanner != NULL); g_hash_table_foreach (scanner->symbol_table, - g_scanner_destroy_symbol_table_entry, NULL); + g_scanner_destroy_symbol_table_entry, NULL); g_hash_table_destroy (scanner->symbol_table); g_scanner_free_value (&scanner->token, &scanner->value); g_scanner_free_value (&scanner->next_token, &scanner->next_value); @@ -236,7 +247,7 @@ g_scanner_destroy (GScanner *scanner) } static void -g_scanner_msg_handler (GScanner *scanner, +g_scanner_msg_handler (GScanner *scanner, gchar *message, gint is_error) { @@ -249,8 +260,8 @@ g_scanner_msg_handler (GScanner *scanner, } void -g_scanner_error (GScanner *scanner, - const gchar *format, +g_scanner_error (GScanner *scanner, + const gchar *format, ...) { g_return_if_fail (scanner != NULL); @@ -341,108 +352,223 @@ g_scanner_input_text (GScanner *scanner, scanner->peeked_char = -1; } +static gint +g_scanner_key_equal (gconstpointer v1, + gconstpointer v2) +{ + register const GScannerKey *key1 = v1; + register const GScannerKey *key2 = v2; + + return (key1->scope_id == key2->scope_id) && (strcmp (key1->symbol, key2->symbol) == 0); +} + +static guint +g_scanner_key_hash (gconstpointer v) +{ + register const GScannerKey *key = v; + register gchar *c; + register guint h; + + h = key->scope_id; + for (c = key->symbol; *c; c++) + { + register guint g; + + h = (h << 4) + *c; + g = h & 0xf0000000; + if (g) + { + h = h ^ (g >> 24); + h = h ^ g; + } + } + + return h; +} + +static inline GScannerKey* +g_scanner_lookup_internal (GScanner *scanner, + guint scope_id, + const gchar *symbol) +{ + register GScannerKey *key_p; + GScannerKey key; + + key.scope_id = scope_id; + + if (!scanner->config->case_sensitive) + { + register gchar *d; + register const gchar *c; + + key.symbol = g_new (gchar, strlen (symbol) + 1); + for (d = key.symbol, c = symbol; *c; c++, d++) + *d = to_lower (*c); + *d = 0; + key_p = g_hash_table_lookup (scanner->symbol_table, &key); + g_free (key.symbol); + } + else + { + key.symbol = (gchar*) symbol; + key_p = g_hash_table_lookup (scanner->symbol_table, &key); + } + + return key_p; +} + void -g_scanner_add_symbol (GScanner *scanner, - const gchar *symbol, - gpointer value) +g_scanner_scope_add_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol, + gpointer value) { - register GScannerHashVal *hash_val; + register GScannerKey *key; g_return_if_fail (scanner != NULL); g_return_if_fail (symbol != NULL); - hash_val = g_scanner_lookup_internal (scanner, symbol); + key = g_scanner_lookup_internal (scanner, scope_id, symbol); - if (!hash_val) + if (!key) { - hash_val = g_new (GScannerHashVal, 1); - hash_val->key = g_strdup (symbol); - hash_val->value = value; + key = g_new (GScannerKey, 1); + key->scope_id = scope_id; + key->symbol = g_strdup (symbol); + key->value = value; if (!scanner->config->case_sensitive) { - register guint i, l; - - l = strlen (hash_val->key); - for (i = 0; i < l; i++) - hash_val->key[i] = to_lower (hash_val->key[i]); + register gchar *c; + + c = key->symbol; + while (*c != 0) + { + *c = to_lower (*c); + c++; + } } - g_hash_table_insert (scanner->symbol_table, hash_val->key, hash_val); + g_hash_table_insert (scanner->symbol_table, key, key); } else - hash_val->value = value; + key->value = value; +} + +void +g_scanner_scope_remove_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol) +{ + register GScannerKey *key; + + g_return_if_fail (scanner != NULL); + g_return_if_fail (symbol != NULL); + + key = g_scanner_lookup_internal (scanner, scope_id, symbol); + + if (key) + { + g_hash_table_remove (scanner->symbol_table, key); + g_free (key->symbol); + g_free (key); + } } gpointer g_scanner_lookup_symbol (GScanner *scanner, const gchar *symbol) { - register GScannerHashVal *hash_val; + register GScannerKey *key; + register guint scope_id; + + g_return_val_if_fail (scanner != NULL, NULL); + + if (!symbol) + return NULL; + + scope_id = scanner->scope_id; + key = g_scanner_lookup_internal (scanner, scope_id, symbol); + if (!key && scope_id && scanner->config->scope_0_fallback) + key = g_scanner_lookup_internal (scanner, 0, symbol); + + if (key) + return key->value; + else + return NULL; +} + +gpointer +g_scanner_scope_lookup_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol) +{ + register GScannerKey *key; g_return_val_if_fail (scanner != NULL, NULL); if (!symbol) return NULL; - hash_val = g_scanner_lookup_internal (scanner, symbol); + key = g_scanner_lookup_internal (scanner, scope_id, symbol); - if (hash_val) - return hash_val->value; + if (key) + return key->value; else return NULL; } +guint +g_scanner_set_scope (GScanner *scanner, + guint scope_id) +{ + register guint old_scope_id; + + g_return_val_if_fail (scanner != NULL, 0); + + old_scope_id = scanner->scope_id; + scanner->scope_id = scope_id; + + return old_scope_id; +} + static void -g_scanner_foreach_internal (gpointer key, - gpointer value, - gpointer user_data) +g_scanner_foreach_internal (gpointer _key, + gpointer _value, + gpointer _user_data) { - register GScannerHashVal *hash_val; + register GScannerKey *key; + register gpointer *d; register GHFunc func; register gpointer func_data; - register gpointer *d; + register guint *scope_id; - d = user_data; - func = (GHFunc)d[0]; + d = _user_data; + func = (GHFunc) d[0]; func_data = d[1]; - hash_val = value; + scope_id = d[2]; + key = _value; - func (key, hash_val->value, func_data); + if (key->scope_id == *scope_id) + func (key->symbol, key->value, func_data); } void -g_scanner_foreach_symbol (GScanner *scanner, - GHFunc func, - gpointer func_data) +g_scanner_scope_foreach_symbol (GScanner *scanner, + guint scope_id, + GHFunc func, + gpointer func_data) { - gpointer d[2]; + gpointer d[3]; g_return_if_fail (scanner != NULL); - d[0] = (gpointer)func; + d[0] = (gpointer) func; d[1] = func_data; + d[2] = &scope_id; g_hash_table_foreach (scanner->symbol_table, g_scanner_foreach_internal, d); } void -g_scanner_remove_symbol (GScanner *scanner, - const gchar *symbol) -{ - register GScannerHashVal *hash_val; - - g_return_if_fail (scanner != NULL); - - hash_val = g_scanner_lookup_internal (scanner, symbol); - - if (hash_val) - { - g_hash_table_remove (scanner->symbol_table, hash_val->key); - g_free (hash_val->key); - g_free (hash_val); - } -} - -void g_scanner_freeze_symbol_table (GScanner *scanner) { g_return_if_fail (scanner != NULL); @@ -545,31 +671,6 @@ g_scanner_eof (GScanner *scanner) return scanner->token == G_TOKEN_EOF; } -static GScannerHashVal* -g_scanner_lookup_internal (GScanner *scanner, - const gchar *symbol) -{ - register GScannerHashVal *hash_val; - - if (!scanner->config->case_sensitive) - { - register gchar *buffer; - register guint i, l; - - l = strlen (symbol); - buffer = g_new (gchar, l + 1); - for (i = 0; i < l; i++) - buffer[i] = to_lower (symbol[i]); - buffer[i] = 0; - hash_val = g_hash_table_lookup (scanner->symbol_table, buffer); - g_free (buffer); - } - else - hash_val = g_hash_table_lookup (scanner->symbol_table, (gchar*) symbol); - - return hash_val; -} - static guchar g_scanner_peek_next_char (GScanner *scanner) { @@ -676,7 +777,7 @@ g_scanner_unexp_token (GScanner *scanner, register guint expected_string_len; register gchar *message_prefix; register gboolean print_unexp; - void (*msg_handler) (GScanner*, const gchar*, ...); + void (*msg_handler) (GScanner*, const gchar*, ...); g_return_if_fail (scanner != NULL); @@ -944,7 +1045,7 @@ gint g_scanner_stat_mode (const gchar *filename) { struct stat *stat_buf; - gint st_mode; + gint st_mode; stat_buf = g_new0 (struct stat, 1); @@ -1001,19 +1102,19 @@ g_scanner_get_token_i (GScanner *scanner, switch (*token_p) { - case G_TOKEN_IDENTIFIER: + case G_TOKEN_IDENTIFIER: if (scanner->config->identifier_2_string) *token_p = G_TOKEN_STRING; break; - case G_TOKEN_SYMBOL: + case G_TOKEN_SYMBOL: if (scanner->config->symbol_2_token) *token_p = (GTokenType) value_p->v_symbol; break; - case G_TOKEN_BINARY: - case G_TOKEN_OCTAL: - case G_TOKEN_HEX: + case G_TOKEN_BINARY: + case G_TOKEN_OCTAL: + case G_TOKEN_HEX: if (scanner->config->numbers_2_int) *token_p = G_TOKEN_INT; break; @@ -1531,15 +1632,19 @@ g_scanner_get_token_ll (GScanner *scanner, if (token == G_TOKEN_IDENTIFIER && config->scan_symbols) { - register GScannerHashVal *hash_val; - - hash_val = g_scanner_lookup_internal (scanner, value.v_identifier); + register GScannerKey *key; + register guint scope_id; + + scope_id = scanner->scope_id; + key = g_scanner_lookup_internal (scanner, scope_id, value.v_identifier); + if (!key && scope_id && scanner->config->scope_0_fallback) + key = g_scanner_lookup_internal (scanner, 0, value.v_identifier); - if (hash_val) + if (key) { g_free (value.v_identifier); token = G_TOKEN_SYMBOL; - value.v_symbol = hash_val->value; + value.v_symbol = key->value; } } -- 2.7.4