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:
Tim Janik
1997-12-23 02:09:34 +00:00
parent b44565f3e4
commit e3956c289a
5 changed files with 1600 additions and 205 deletions

View File

@ -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>
* glist.c: minor optimizations:

View File

@ -13,8 +13,9 @@ libglib_la_SOURCES = \
gslist.c \
gtimer.c \
gtree.c \
gutils.c \
gstring.c
gstring.c \
gscanner.c \
gutils.c
include_HEADERS = \
glib.h

View File

@ -597,6 +597,8 @@ void g_print (gchar *format, ...);
/* Utility functions
*/
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_strsignal (gint signum);
@ -682,7 +684,6 @@ GArray* g_rarray_truncate (GArray *array,
gint length,
gint size);
/* Hash Functions
*/
gint g_string_equal (gpointer v,
@ -690,6 +691,178 @@ gint g_string_equal (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
}
#endif /* __cplusplus */

1134
glib/gscanner.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,9 @@
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include "glib.h"
@ -43,6 +45,81 @@ g_strdup (const gchar *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*
g_strerror (gint errnum)
{