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>
 | 
			
		||||
 | 
			
		||||
	* glist.c: minor optimizations:
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										175
									
								
								glib/glib_pre2.h
									
									
									
									
									
								
							
							
						
						
									
										175
									
								
								glib/glib_pre2.h
									
									
									
									
									
								
							@ -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
									
								
							
							
						
						
									
										1134
									
								
								glib/gscanner.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -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)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user