+Thu Jul 23 00:29:14 1998 Tim Janik <timj@gtk.org>
+
+ * 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 <jirka@5z.com>
* glib.h: typo fixed for alphas for gint64
+Thu Jul 23 00:29:14 1998 Tim Janik <timj@gtk.org>
+
+ * 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 <jirka@5z.com>
* glib.h: typo fixed for alphas for gint64
+Thu Jul 23 00:29:14 1998 Tim Janik <timj@gtk.org>
+
+ * 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 <jirka@5z.com>
* glib.h: typo fixed for alphas for gint64
+Thu Jul 23 00:29:14 1998 Tim Janik <timj@gtk.org>
+
+ * 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 <jirka@5z.com>
* glib.h: typo fixed for alphas for gint64
+Thu Jul 23 00:29:14 1998 Tim Janik <timj@gtk.org>
+
+ * 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 <jirka@5z.com>
* glib.h: typo fixed for alphas for gint64
+Thu Jul 23 00:29:14 1998 Tim Janik <timj@gtk.org>
+
+ * 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 <jirka@5z.com>
* glib.h: typo fixed for alphas for gint64
+Thu Jul 23 00:29:14 1998 Tim Janik <timj@gtk.org>
+
+ * 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 <jirka@5z.com>
* glib.h: typo fixed for alphas for gint64
+Thu Jul 23 00:29:14 1998 Tim Janik <timj@gtk.org>
+
+ * 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 <jirka@5z.com>
* glib.h: typo fixed for alphas for gint64
*
* 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
/* 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;
struct _GByteArray
{
guint8 *data;
- guint len;
+ guint len;
};
struct _GPtrArray
{
gpointer *pdata;
- guint len;
+ guint len;
};
struct _GTuples
struct _GDebugKey
{
gchar *key;
- guint value;
+ guint value;
};
struct _GCache { gint dummy; };
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
guint text_len;
gint input_fd;
gint peeked_char;
+ guint scope_id;
/* handler function for _warn and _error */
GScannerMsgFunc msg_handler;
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);
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 */
*
* 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
/* 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;
struct _GByteArray
{
guint8 *data;
- guint len;
+ guint len;
};
struct _GPtrArray
{
gpointer *pdata;
- guint len;
+ guint len;
};
struct _GTuples
struct _GDebugKey
{
gchar *key;
- guint value;
+ guint value;
};
struct _GCache { gint dummy; };
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
guint text_len;
gint input_fd;
gint peeked_char;
+ guint scope_id;
/* handler function for _warn and _error */
GScannerMsgFunc msg_handler;
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);
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 */
/* --- typedefs --- */
-typedef struct _GScannerHashVal GScannerHashVal;
+typedef struct _GScannerKey GScannerKey;
-struct _GScannerHashVal
+struct _GScannerKey
{
- gchar *key;
- gpointer value;
+ guint scope_id;
+ gchar *symbol;
+ gpointer value;
};
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 --- */
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;
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;
}
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
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);
}
static void
-g_scanner_msg_handler (GScanner *scanner,
+g_scanner_msg_handler (GScanner *scanner,
gchar *message,
gint is_error)
{
}
void
-g_scanner_error (GScanner *scanner,
- const gchar *format,
+g_scanner_error (GScanner *scanner,
+ const gchar *format,
...)
{
g_return_if_fail (scanner != NULL);
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)
{
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)
{
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);
g_scanner_stat_mode (const gchar *filename)
{
struct stat *stat_buf;
- gint st_mode;
+ gint st_mode;
stat_buf = g_new0 (struct stat, 1);
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;
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;
}
}
/* 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
/* --- typedefs --- */
-typedef struct _GScannerHashVal GScannerHashVal;
+typedef struct _GScannerKey GScannerKey;
-struct _GScannerHashVal
+struct _GScannerKey
{
- gchar *key;
- gpointer value;
+ guint scope_id;
+ gchar *symbol;
+ gpointer value;
};
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 --- */
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;
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;
}
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
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);
}
static void
-g_scanner_msg_handler (GScanner *scanner,
+g_scanner_msg_handler (GScanner *scanner,
gchar *message,
gint is_error)
{
}
void
-g_scanner_error (GScanner *scanner,
- const gchar *format,
+g_scanner_error (GScanner *scanner,
+ const gchar *format,
...)
{
g_return_if_fail (scanner != NULL);
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)
{
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)
{
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);
g_scanner_stat_mode (const gchar *filename)
{
struct stat *stat_buf;
- gint st_mode;
+ gint st_mode;
stat_buf = g_new0 (struct stat, 1);
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;
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;
}
}