new file for GScanner: Flexible lexical scanner for general purpose. added
* gscanner.c: new file for GScanner: Flexible lexical scanner for
general purpose.
* glib_pre2.h: added GScanner includes. added g_strconcat and g_strtod.
gutils.c (g_strconcat): new function for string concatenation of NULL
terminated parameter list.
(g_strtod): new function to perform best string to double conversion
with or without consideration of the current locale.
-timj
This commit is contained in:
@ -1,3 +1,13 @@
|
|||||||
|
Tue Dec 23 02:49:51 1997 Tim Janik <timj@psynet.net>
|
||||||
|
|
||||||
|
* gscanner.c: new file for GScanner: Flexible lexical scanner for
|
||||||
|
general purpose.
|
||||||
|
* glib_pre2.h: added GScanner includes. added g_strconcat and g_strtod.
|
||||||
|
gutils.c (g_strconcat): new function for string concatenation of NULL
|
||||||
|
terminated parameter list.
|
||||||
|
(g_strtod): new function to perform best string to double conversion
|
||||||
|
with or without consideration of the current locale.
|
||||||
|
|
||||||
Mon Dec 15 19:33:58 1997 Tim Janik <timj@psynet.net>
|
Mon Dec 15 19:33:58 1997 Tim Janik <timj@psynet.net>
|
||||||
|
|
||||||
* glist.c: minor optimizations:
|
* glist.c: minor optimizations:
|
||||||
|
|||||||
@ -13,8 +13,9 @@ libglib_la_SOURCES = \
|
|||||||
gslist.c \
|
gslist.c \
|
||||||
gtimer.c \
|
gtimer.c \
|
||||||
gtree.c \
|
gtree.c \
|
||||||
gutils.c \
|
gstring.c \
|
||||||
gstring.c
|
gscanner.c \
|
||||||
|
gutils.c
|
||||||
|
|
||||||
include_HEADERS = \
|
include_HEADERS = \
|
||||||
glib.h
|
glib.h
|
||||||
|
|||||||
175
glib/glib_pre2.h
175
glib/glib_pre2.h
@ -597,6 +597,8 @@ void g_print (gchar *format, ...);
|
|||||||
/* Utility functions
|
/* Utility functions
|
||||||
*/
|
*/
|
||||||
gchar* g_strdup (const gchar *str);
|
gchar* g_strdup (const gchar *str);
|
||||||
|
gchar* g_strconcat (const gchar *string1, ...); /* NULL terminated */
|
||||||
|
gdouble g_strtod (const gchar *nptr, gchar **endptr);
|
||||||
gchar* g_strerror (gint errnum);
|
gchar* g_strerror (gint errnum);
|
||||||
gchar* g_strsignal (gint signum);
|
gchar* g_strsignal (gint signum);
|
||||||
|
|
||||||
@ -682,7 +684,6 @@ GArray* g_rarray_truncate (GArray *array,
|
|||||||
gint length,
|
gint length,
|
||||||
gint size);
|
gint size);
|
||||||
|
|
||||||
|
|
||||||
/* Hash Functions
|
/* Hash Functions
|
||||||
*/
|
*/
|
||||||
gint g_string_equal (gpointer v,
|
gint g_string_equal (gpointer v,
|
||||||
@ -690,6 +691,178 @@ gint g_string_equal (gpointer v,
|
|||||||
guint g_string_hash (gpointer v);
|
guint g_string_hash (gpointer v);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* GScanner: Flexible lexical scanner for general purpose.
|
||||||
|
* Copyright (C) 1997 Tim Janik
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Character sets */
|
||||||
|
#define G_CSET_A_2_Z "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
#define G_CSET_a_2_z "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
#define G_CSET_LATINC "\300\301\302\303\304\305\306"\
|
||||||
|
"\307\310\311\312\313\314\315\316\317\320"\
|
||||||
|
"\321\322\323\324\325\326"\
|
||||||
|
"\330\331\332\333\334\335\336"
|
||||||
|
#define G_CSET_LATINS "\337\340\341\342\343\344\345\346"\
|
||||||
|
"\347\350\351\352\353\354\355\356\357\360"\
|
||||||
|
"\361\362\363\364\365\366"\
|
||||||
|
"\370\371\372\373\374\375\376\377"
|
||||||
|
|
||||||
|
typedef union _GValue GValue;
|
||||||
|
typedef struct _GScannerConfig GScannerConfig;
|
||||||
|
typedef struct _GScanner GScanner;
|
||||||
|
|
||||||
|
/* Error types */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
G_ERR_UNKNOWN,
|
||||||
|
G_ERR_UNEXP_EOF,
|
||||||
|
G_ERR_UNEXP_EOF_IN_STRING,
|
||||||
|
G_ERR_UNEXP_EOF_IN_COMMENT,
|
||||||
|
G_ERR_NON_DIGIT_IN_CONST,
|
||||||
|
G_ERR_DIGIT_RADIX,
|
||||||
|
G_ERR_FLOAT_RADIX,
|
||||||
|
G_ERR_FLOAT_MALFORMED
|
||||||
|
} GErrorType;
|
||||||
|
|
||||||
|
/* Token types */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
G_TOKEN_EOF = 0,
|
||||||
|
|
||||||
|
G_TOKEN_LEFT_PAREN = '(',
|
||||||
|
G_TOKEN_RIGHT_PAREN = ')',
|
||||||
|
G_TOKEN_LEFT_CURLY = '{',
|
||||||
|
G_TOKEN_RIGHT_CURLY = '}',
|
||||||
|
G_TOKEN_LEFT_BRACE = '[',
|
||||||
|
G_TOKEN_RIGHT_BRACE = ']',
|
||||||
|
G_TOKEN_EQUAL_SIGN = '=',
|
||||||
|
G_TOKEN_COMMA = ',',
|
||||||
|
|
||||||
|
G_TOKEN_NONE = 256,
|
||||||
|
|
||||||
|
G_TOKEN_ERROR,
|
||||||
|
|
||||||
|
G_TOKEN_CHAR,
|
||||||
|
G_TOKEN_BINARY,
|
||||||
|
G_TOKEN_OCTAL,
|
||||||
|
G_TOKEN_INT,
|
||||||
|
G_TOKEN_HEX,
|
||||||
|
G_TOKEN_FLOAT,
|
||||||
|
G_TOKEN_STRING,
|
||||||
|
|
||||||
|
G_TOKEN_SYMBOL,
|
||||||
|
G_TOKEN_IDENTIFIER,
|
||||||
|
G_TOKEN_IDENTIFIER_NULL,
|
||||||
|
|
||||||
|
G_TOKEN_COMMENT_SINGLE,
|
||||||
|
G_TOKEN_COMMENT_MULTI,
|
||||||
|
G_TOKEN_LAST
|
||||||
|
} GTokenType;
|
||||||
|
|
||||||
|
union _GValue
|
||||||
|
{
|
||||||
|
gpointer v_symbol;
|
||||||
|
gchar *v_identifier;
|
||||||
|
gulong v_binary;
|
||||||
|
gulong v_octal;
|
||||||
|
gulong v_int;
|
||||||
|
gdouble v_float;
|
||||||
|
gulong v_hex;
|
||||||
|
gchar *v_string;
|
||||||
|
gchar *v_comment;
|
||||||
|
guchar v_char;
|
||||||
|
guint v_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GScannerConfig
|
||||||
|
{
|
||||||
|
/* Character sets
|
||||||
|
*/
|
||||||
|
gchar *cset_skip_characters; /* default: " \t\n" */
|
||||||
|
gchar *cset_identifier_first;
|
||||||
|
gchar *cset_identifier_nth;
|
||||||
|
gchar *cpair_comment_single; /* default: "#\n" */
|
||||||
|
|
||||||
|
/* Should symbol lookup work case sensitive?
|
||||||
|
*/
|
||||||
|
guint32 case_sensitive : 1;
|
||||||
|
|
||||||
|
/* Boolean values to be adjusted "on the fly"
|
||||||
|
* to configure scanning behaviour.
|
||||||
|
*/
|
||||||
|
guint32 skip_comment_multi : 1; /* C like comment */
|
||||||
|
guint32 skip_comment_single : 1; /* single line comment */
|
||||||
|
guint32 scan_comment_multi : 1; /* scan multi line comments? */
|
||||||
|
guint32 scan_identifier : 1;
|
||||||
|
guint32 scan_identifier_1char : 1;
|
||||||
|
guint32 scan_identifier_NULL : 1;
|
||||||
|
guint32 scan_symbols : 1;
|
||||||
|
guint32 scan_binary : 1;
|
||||||
|
guint32 scan_octal : 1;
|
||||||
|
guint32 scan_float : 1;
|
||||||
|
guint32 scan_hex : 1; /* `0x0ff0' */
|
||||||
|
guint32 scan_hex_dollar : 1; /* `$0ff0' */
|
||||||
|
guint32 scan_string_sq : 1; /* string: 'anything' */
|
||||||
|
guint32 scan_string_dq : 1; /* string: "\\-escapes!\n" */
|
||||||
|
guint32 numbers_2_int : 1; /* bin, octal, hex => int */
|
||||||
|
guint32 int_2_float : 1; /* int => G_TOKEN_FLOAT? */
|
||||||
|
guint32 identifier_2_string : 1;
|
||||||
|
guint32 char_2_token : 1; /* return G_TOKEN_CHAR? */
|
||||||
|
guint32 symbol_2_token : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GScanner
|
||||||
|
{
|
||||||
|
/* unused portions */
|
||||||
|
gpointer user_data;
|
||||||
|
const gchar *input_name;
|
||||||
|
guint parse_errors;
|
||||||
|
guint max_parse_errors;
|
||||||
|
|
||||||
|
/* maintained/used by the g_scanner_*() functions */
|
||||||
|
GScannerConfig *config;
|
||||||
|
GTokenType token;
|
||||||
|
GValue value;
|
||||||
|
guint line;
|
||||||
|
guint position;
|
||||||
|
|
||||||
|
/* to be considered private */
|
||||||
|
GTokenType next_token;
|
||||||
|
GValue next_value;
|
||||||
|
guint next_line;
|
||||||
|
guint next_position;
|
||||||
|
GHashTable *symbol_table;
|
||||||
|
const gchar *text;
|
||||||
|
guint text_len;
|
||||||
|
gint input_fd;
|
||||||
|
gint peeked_char;
|
||||||
|
};
|
||||||
|
|
||||||
|
GScanner* g_scanner_new (GScannerConfig *config_templ);
|
||||||
|
void g_scanner_destroy (GScanner *scanner);
|
||||||
|
void g_scanner_input_file (GScanner *scanner,
|
||||||
|
gint input_fd);
|
||||||
|
void g_scanner_input_text (GScanner *scanner,
|
||||||
|
const gchar *text,
|
||||||
|
guint text_len);
|
||||||
|
GTokenType g_scanner_get_next_token (GScanner *scanner);
|
||||||
|
GTokenType g_scanner_peek_next_token (GScanner *scanner);
|
||||||
|
GTokenType g_scanner_cur_token (GScanner *scanner);
|
||||||
|
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,
|
||||||
|
const gchar *symbol,
|
||||||
|
gpointer value);
|
||||||
|
gpointer g_scanner_lookup_symbol (GScanner *scanner,
|
||||||
|
const gchar *symbol);
|
||||||
|
void g_scanner_remove_symbol (GScanner *scanner,
|
||||||
|
const gchar *symbol);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|||||||
1134
glib/gscanner.c
Normal file
1134
glib/gscanner.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <locale.h>
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
|
|
||||||
@ -43,6 +45,81 @@ g_strdup (const gchar *str)
|
|||||||
return new_str;
|
return new_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gchar*
|
||||||
|
g_strconcat (const gchar *string1, ...)
|
||||||
|
{
|
||||||
|
guint l;
|
||||||
|
va_list args;
|
||||||
|
gchar *s;
|
||||||
|
gchar *concat;
|
||||||
|
|
||||||
|
g_return_val_if_fail (string1 != NULL, NULL);
|
||||||
|
|
||||||
|
l = 1 + strlen (string1);
|
||||||
|
va_start (args, string1);
|
||||||
|
s = va_arg (args, gchar*);
|
||||||
|
while (s)
|
||||||
|
{
|
||||||
|
l += strlen (s);
|
||||||
|
s = va_arg (args, gchar*);
|
||||||
|
}
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
concat = g_new (gchar, l);
|
||||||
|
concat[0] = 0;
|
||||||
|
|
||||||
|
strcat (concat, string1);
|
||||||
|
va_start (args, string1);
|
||||||
|
s = va_arg (args, gchar*);
|
||||||
|
while (s)
|
||||||
|
{
|
||||||
|
strcat (concat, s);
|
||||||
|
s = va_arg (args, gchar*);
|
||||||
|
}
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
return concat;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
g_strtod (const gchar *nptr,
|
||||||
|
gchar **endptr)
|
||||||
|
{
|
||||||
|
gchar *fail_pos_1;
|
||||||
|
gchar *fail_pos_2;
|
||||||
|
gdouble val_1;
|
||||||
|
gdouble val_2 = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (nptr != NULL, 0);
|
||||||
|
|
||||||
|
fail_pos_1 = NULL;
|
||||||
|
fail_pos_2 = NULL;
|
||||||
|
|
||||||
|
val_1 = strtod (nptr, &fail_pos_1);
|
||||||
|
|
||||||
|
if (fail_pos_1 && fail_pos_1[0] != 0)
|
||||||
|
{
|
||||||
|
gchar *old_locale;
|
||||||
|
|
||||||
|
old_locale = setlocale (LC_NUMERIC, "C");
|
||||||
|
val_2 = strtod (nptr, &fail_pos_2);
|
||||||
|
setlocale (LC_NUMERIC, old_locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
|
||||||
|
{
|
||||||
|
if (endptr)
|
||||||
|
*endptr = fail_pos_1;
|
||||||
|
return val_1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (endptr)
|
||||||
|
*endptr = fail_pos_2;
|
||||||
|
return val_2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gchar*
|
gchar*
|
||||||
g_strerror (gint errnum)
|
g_strerror (gint errnum)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user