1998-06-11 01:21:14 +02:00
|
|
|
/* GLIB - Library of useful routines for C programming
|
|
|
|
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
|
|
|
*
|
|
|
|
* GScanner: Flexible lexical scanner for general purpose.
|
|
|
|
* Copyright (C) 1997, 1998 Tim Janik
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
2000-07-26 13:02:02 +02:00
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
1998-06-11 01:21:14 +02:00
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 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
|
2000-07-26 13:02:02 +02:00
|
|
|
* Lesser General Public License for more details.
|
1998-06-11 01:21:14 +02:00
|
|
|
*
|
2000-07-26 13:02:02 +02:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
1998-06-11 01:21:14 +02:00
|
|
|
* License along with this library; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
1998-12-15 06:28:02 +01:00
|
|
|
|
1999-02-24 07:14:27 +01:00
|
|
|
/*
|
2000-07-26 13:02:02 +02:00
|
|
|
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
|
1999-02-24 07:14:27 +01:00
|
|
|
* file for a list of people on the GLib Team. See the ChangeLog
|
|
|
|
* files for a list of changes. These files are distributed with
|
|
|
|
* GLib at ftp://ftp.gtk.org/pub/gtk/.
|
|
|
|
*/
|
|
|
|
|
1998-12-15 06:28:02 +01:00
|
|
|
/*
|
|
|
|
* MT safe
|
|
|
|
*/
|
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
#define __gscanner_c__
|
|
|
|
|
1998-11-01 05:19:54 +01:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
removed dummy structure definitions for struct _GCache, _GTree, _GTimer,
Tue Oct 27 03:00:50 1998 Tim Janik <timj@gtk.org>
* glib.h: removed dummy structure definitions for struct _GCache,
_GTree, _GTimer, _GMemChunk, _GListAllocator and _GStringChunk.
* gutils.c: implement glib's inline functions _after_ all include
statements have been processed.
removed Tor's MAXPATHLEN check since there already was one supplied
further down in this file.
(LibMain): special cased the #ifdef __LCC__ case for NATIVE_WIN32,
since lcc maybe used on other platforms as well. why in hell is this
stuff required?
(g_get_any_init): for windows, if the user name is supplied, use it as
realname also.
in general, if there is no homedir specified, use the tmpdir that
we already figured.
* gtimer.c (g_timer_elapsed): changed a g_assert() statement to
g_return_if_fail().
* applied glib-tml-981020-0.patch for WIN32 portability, added some
comments and g_return_if_fail() statements, minor indentation fixes.
ChangeLog entry from Tor Lillqvist is appended.
* glib.h (struct dirent): use lower case structure members.
* glib.h:
* makefile.lcc:
* makefile.msc:
s/COMPILING_GLIB/GLIB_COMPILATION/
1998-10-20: Tor Lillqvist <tml@iki.fi>
* README.win32 glib.def gmodule.def
* glibconfig.h.win32 gmodule/gmoduleconf.h.win32:
New files for the Windows port. The .def files list exported
symbols for the Microsoft linker and compatibles.
* configure.in:
Added checks for some platform-dependent headers: pwd.h sys/param.h
sys/select.h sys/time.h sys/times.h unistd.h, and the function lstat.
* gerror.c:
Conditionalized inclusion of system-dependent headers. Changes
for Windows: no gdb to do a stack trace. Just call abort().
* glib.h:
Changes for Windows:
Added macros G_DIR_SEPARATOR, G_DIR_SEPARATOR_S for
platform-dependent file name syntax elements. Added macros
G_SEARCHPATH_SEPARATOR, G_SEARCHPATH_SEPARATOR_S for
platform-dependent search path syntax conventions.
Added pragmas for Microsoft C to make it more pedantic.
Marked GLib's global variables for export from DLL.
Added the function g_strescape that escapes backslashes.
Added functions g_path_is_absolute and g_path_skip_root to
handle platform-dependent file name syntax.
Added the function g_getenv that expands environment variables
that contain references to other environment variables, as is
typical on Windows NT.
Added the GIOChannel structure which is used to encapsulate the
IPC mechanism used by the GIMP's plug-ins, and possibly other
things later. On Unix a GIOChannel encapsulates just a file
descriptor. On Windows it contains a file handle from _pipe() and a
few other things related to the implementation of gdk_input_add
and GIMP plug-in communication. Subject to change.
Removed duplicate declarations of the version variables.
For the Microsoft compiler, declare own implementation of
ftruncate and the <dirent.h> functions.
* gmem.c:
Define a symbolic name for the profiling table size.
* gmessages.c:
Conditionalized inclusion of unistd.h. On Windows, output using
stdio to stdout.
* gscanner.c:
Conditionalized inclusion of unistd.h. Added changes for
Microsoft C. Added CR to the skipped character set. Added small
workaround for MSC compiler bug in g_scanner_cur_value.
* gstrfuncs.c:
Added the function g_strescape, which escapes the backslash
character. Needed especially when printing Windows filenames.
* gtimer.c:
Conditionalized inclusion of unistd.h and sys/time.h. Added
implementations for Windows.
* gutils.c:
Conditionalized inclusion of platform-dependent headers. Use
the platform-independent file name syntax macros.
Conditionalize code on platform-dependent features. Added the
functions g_path_is_absolute g_path_skip_root and g_getenv.
Added the GIOChannel-related functions. Added
compiler-dependent Unix compatibility functions for Windows.
* makefile.lcc makefile.msc:
New files. Compiler-specific makefiles for LCC-Win32 and
Microsoft C. Only Microsoft C is actually supported currently.
* testglib.c:
Added pathname check cases for Windows. Added workaround for
bug in the Microsoft runtime library. Improved some tests a bit.
Tue Oct 27 04:00:11 1998 Tim Janik <timj@gtk.org>
* testgmodule.c (main): changed the #ifdef WIN32 test to NATIVE_WIN32,
this needs to be more constistent throughout the code, do we go for
NATIVE_WIN32 or WIN32?
* gmodule.c (LibMain): special cased the #ifdef __LCC__ case for
NATIVE_WIN32, since lcc maybe used on other platforms as well.
* libgplugin_a.c (LibMain):
* libgplugin_b.c (LibMain):
likewise. not sure i like this special requirement for lcc in here.
* gmodule-dl.c (_g_module_build_path):
feature empty "" directories and prepend the module name with "lib".
* gmodule-dld.c (_g_module_build_path):
* gmodule-win32.c (_g_module_build_path):
feature empty "" directories.
* we need some more magic in the _g_module_build_path variants
so we don't append/prepend lib and .so, .sl or .dll for those names
that already contain it.
* applied patch from Tor Lillqvist for g_module_build_path() and
windows support.
1998-10-20: Tor Lillqvist <tml@iki.fi>
* gmodule/gmodule-win32.c:
New file.
* gmodule/gmodule.c gmodule/gmodule.h:
Added the funcion g_module_build_path that builds the path to
a module file, decorating the name according to the system's
conventions. Added the Windows implementation.
* gmodule/libgplugin_a.c gmodule/libgplugin_b.c:
Added LibMain for LCC-Win32.
* gmodule/testgmodule.c:
Handle Windows dll names.
1998-10-27 05:11:34 +01:00
|
|
|
#include "glib.h"
|
|
|
|
#ifdef HAVE_UNISTD_H
|
1998-06-11 01:21:14 +02:00
|
|
|
#include <unistd.h>
|
removed dummy structure definitions for struct _GCache, _GTree, _GTimer,
Tue Oct 27 03:00:50 1998 Tim Janik <timj@gtk.org>
* glib.h: removed dummy structure definitions for struct _GCache,
_GTree, _GTimer, _GMemChunk, _GListAllocator and _GStringChunk.
* gutils.c: implement glib's inline functions _after_ all include
statements have been processed.
removed Tor's MAXPATHLEN check since there already was one supplied
further down in this file.
(LibMain): special cased the #ifdef __LCC__ case for NATIVE_WIN32,
since lcc maybe used on other platforms as well. why in hell is this
stuff required?
(g_get_any_init): for windows, if the user name is supplied, use it as
realname also.
in general, if there is no homedir specified, use the tmpdir that
we already figured.
* gtimer.c (g_timer_elapsed): changed a g_assert() statement to
g_return_if_fail().
* applied glib-tml-981020-0.patch for WIN32 portability, added some
comments and g_return_if_fail() statements, minor indentation fixes.
ChangeLog entry from Tor Lillqvist is appended.
* glib.h (struct dirent): use lower case structure members.
* glib.h:
* makefile.lcc:
* makefile.msc:
s/COMPILING_GLIB/GLIB_COMPILATION/
1998-10-20: Tor Lillqvist <tml@iki.fi>
* README.win32 glib.def gmodule.def
* glibconfig.h.win32 gmodule/gmoduleconf.h.win32:
New files for the Windows port. The .def files list exported
symbols for the Microsoft linker and compatibles.
* configure.in:
Added checks for some platform-dependent headers: pwd.h sys/param.h
sys/select.h sys/time.h sys/times.h unistd.h, and the function lstat.
* gerror.c:
Conditionalized inclusion of system-dependent headers. Changes
for Windows: no gdb to do a stack trace. Just call abort().
* glib.h:
Changes for Windows:
Added macros G_DIR_SEPARATOR, G_DIR_SEPARATOR_S for
platform-dependent file name syntax elements. Added macros
G_SEARCHPATH_SEPARATOR, G_SEARCHPATH_SEPARATOR_S for
platform-dependent search path syntax conventions.
Added pragmas for Microsoft C to make it more pedantic.
Marked GLib's global variables for export from DLL.
Added the function g_strescape that escapes backslashes.
Added functions g_path_is_absolute and g_path_skip_root to
handle platform-dependent file name syntax.
Added the function g_getenv that expands environment variables
that contain references to other environment variables, as is
typical on Windows NT.
Added the GIOChannel structure which is used to encapsulate the
IPC mechanism used by the GIMP's plug-ins, and possibly other
things later. On Unix a GIOChannel encapsulates just a file
descriptor. On Windows it contains a file handle from _pipe() and a
few other things related to the implementation of gdk_input_add
and GIMP plug-in communication. Subject to change.
Removed duplicate declarations of the version variables.
For the Microsoft compiler, declare own implementation of
ftruncate and the <dirent.h> functions.
* gmem.c:
Define a symbolic name for the profiling table size.
* gmessages.c:
Conditionalized inclusion of unistd.h. On Windows, output using
stdio to stdout.
* gscanner.c:
Conditionalized inclusion of unistd.h. Added changes for
Microsoft C. Added CR to the skipped character set. Added small
workaround for MSC compiler bug in g_scanner_cur_value.
* gstrfuncs.c:
Added the function g_strescape, which escapes the backslash
character. Needed especially when printing Windows filenames.
* gtimer.c:
Conditionalized inclusion of unistd.h and sys/time.h. Added
implementations for Windows.
* gutils.c:
Conditionalized inclusion of platform-dependent headers. Use
the platform-independent file name syntax macros.
Conditionalize code on platform-dependent features. Added the
functions g_path_is_absolute g_path_skip_root and g_getenv.
Added the GIOChannel-related functions. Added
compiler-dependent Unix compatibility functions for Windows.
* makefile.lcc makefile.msc:
New files. Compiler-specific makefiles for LCC-Win32 and
Microsoft C. Only Microsoft C is actually supported currently.
* testglib.c:
Added pathname check cases for Windows. Added workaround for
bug in the Microsoft runtime library. Improved some tests a bit.
Tue Oct 27 04:00:11 1998 Tim Janik <timj@gtk.org>
* testgmodule.c (main): changed the #ifdef WIN32 test to NATIVE_WIN32,
this needs to be more constistent throughout the code, do we go for
NATIVE_WIN32 or WIN32?
* gmodule.c (LibMain): special cased the #ifdef __LCC__ case for
NATIVE_WIN32, since lcc maybe used on other platforms as well.
* libgplugin_a.c (LibMain):
* libgplugin_b.c (LibMain):
likewise. not sure i like this special requirement for lcc in here.
* gmodule-dl.c (_g_module_build_path):
feature empty "" directories and prepend the module name with "lib".
* gmodule-dld.c (_g_module_build_path):
* gmodule-win32.c (_g_module_build_path):
feature empty "" directories.
* we need some more magic in the _g_module_build_path variants
so we don't append/prepend lib and .so, .sl or .dll for those names
that already contain it.
* applied patch from Tor Lillqvist for g_module_build_path() and
windows support.
1998-10-20: Tor Lillqvist <tml@iki.fi>
* gmodule/gmodule-win32.c:
New file.
* gmodule/gmodule.c gmodule/gmodule.h:
Added the funcion g_module_build_path that builds the path to
a module file, decorating the name according to the system's
conventions. Added the Windows implementation.
* gmodule/libgplugin_a.c gmodule/libgplugin_b.c:
Added LibMain for LCC-Win32.
* gmodule/testgmodule.c:
Handle Windows dll names.
1998-10-27 05:11:34 +01:00
|
|
|
#endif
|
1998-06-11 01:21:14 +02:00
|
|
|
#include <errno.h>
|
|
|
|
#include <sys/types.h> /* needed for sys/stat.h */
|
|
|
|
#include <sys/stat.h>
|
1999-10-04 04:32:50 +02:00
|
|
|
#ifdef G_OS_WIN32
|
removed dummy structure definitions for struct _GCache, _GTree, _GTimer,
Tue Oct 27 03:00:50 1998 Tim Janik <timj@gtk.org>
* glib.h: removed dummy structure definitions for struct _GCache,
_GTree, _GTimer, _GMemChunk, _GListAllocator and _GStringChunk.
* gutils.c: implement glib's inline functions _after_ all include
statements have been processed.
removed Tor's MAXPATHLEN check since there already was one supplied
further down in this file.
(LibMain): special cased the #ifdef __LCC__ case for NATIVE_WIN32,
since lcc maybe used on other platforms as well. why in hell is this
stuff required?
(g_get_any_init): for windows, if the user name is supplied, use it as
realname also.
in general, if there is no homedir specified, use the tmpdir that
we already figured.
* gtimer.c (g_timer_elapsed): changed a g_assert() statement to
g_return_if_fail().
* applied glib-tml-981020-0.patch for WIN32 portability, added some
comments and g_return_if_fail() statements, minor indentation fixes.
ChangeLog entry from Tor Lillqvist is appended.
* glib.h (struct dirent): use lower case structure members.
* glib.h:
* makefile.lcc:
* makefile.msc:
s/COMPILING_GLIB/GLIB_COMPILATION/
1998-10-20: Tor Lillqvist <tml@iki.fi>
* README.win32 glib.def gmodule.def
* glibconfig.h.win32 gmodule/gmoduleconf.h.win32:
New files for the Windows port. The .def files list exported
symbols for the Microsoft linker and compatibles.
* configure.in:
Added checks for some platform-dependent headers: pwd.h sys/param.h
sys/select.h sys/time.h sys/times.h unistd.h, and the function lstat.
* gerror.c:
Conditionalized inclusion of system-dependent headers. Changes
for Windows: no gdb to do a stack trace. Just call abort().
* glib.h:
Changes for Windows:
Added macros G_DIR_SEPARATOR, G_DIR_SEPARATOR_S for
platform-dependent file name syntax elements. Added macros
G_SEARCHPATH_SEPARATOR, G_SEARCHPATH_SEPARATOR_S for
platform-dependent search path syntax conventions.
Added pragmas for Microsoft C to make it more pedantic.
Marked GLib's global variables for export from DLL.
Added the function g_strescape that escapes backslashes.
Added functions g_path_is_absolute and g_path_skip_root to
handle platform-dependent file name syntax.
Added the function g_getenv that expands environment variables
that contain references to other environment variables, as is
typical on Windows NT.
Added the GIOChannel structure which is used to encapsulate the
IPC mechanism used by the GIMP's plug-ins, and possibly other
things later. On Unix a GIOChannel encapsulates just a file
descriptor. On Windows it contains a file handle from _pipe() and a
few other things related to the implementation of gdk_input_add
and GIMP plug-in communication. Subject to change.
Removed duplicate declarations of the version variables.
For the Microsoft compiler, declare own implementation of
ftruncate and the <dirent.h> functions.
* gmem.c:
Define a symbolic name for the profiling table size.
* gmessages.c:
Conditionalized inclusion of unistd.h. On Windows, output using
stdio to stdout.
* gscanner.c:
Conditionalized inclusion of unistd.h. Added changes for
Microsoft C. Added CR to the skipped character set. Added small
workaround for MSC compiler bug in g_scanner_cur_value.
* gstrfuncs.c:
Added the function g_strescape, which escapes the backslash
character. Needed especially when printing Windows filenames.
* gtimer.c:
Conditionalized inclusion of unistd.h and sys/time.h. Added
implementations for Windows.
* gutils.c:
Conditionalized inclusion of platform-dependent headers. Use
the platform-independent file name syntax macros.
Conditionalize code on platform-dependent features. Added the
functions g_path_is_absolute g_path_skip_root and g_getenv.
Added the GIOChannel-related functions. Added
compiler-dependent Unix compatibility functions for Windows.
* makefile.lcc makefile.msc:
New files. Compiler-specific makefiles for LCC-Win32 and
Microsoft C. Only Microsoft C is actually supported currently.
* testglib.c:
Added pathname check cases for Windows. Added workaround for
bug in the Microsoft runtime library. Improved some tests a bit.
Tue Oct 27 04:00:11 1998 Tim Janik <timj@gtk.org>
* testgmodule.c (main): changed the #ifdef WIN32 test to NATIVE_WIN32,
this needs to be more constistent throughout the code, do we go for
NATIVE_WIN32 or WIN32?
* gmodule.c (LibMain): special cased the #ifdef __LCC__ case for
NATIVE_WIN32, since lcc maybe used on other platforms as well.
* libgplugin_a.c (LibMain):
* libgplugin_b.c (LibMain):
likewise. not sure i like this special requirement for lcc in here.
* gmodule-dl.c (_g_module_build_path):
feature empty "" directories and prepend the module name with "lib".
* gmodule-dld.c (_g_module_build_path):
* gmodule-win32.c (_g_module_build_path):
feature empty "" directories.
* we need some more magic in the _g_module_build_path variants
so we don't append/prepend lib and .so, .sl or .dll for those names
that already contain it.
* applied patch from Tor Lillqvist for g_module_build_path() and
windows support.
1998-10-20: Tor Lillqvist <tml@iki.fi>
* gmodule/gmodule-win32.c:
New file.
* gmodule/gmodule.c gmodule/gmodule.h:
Added the funcion g_module_build_path that builds the path to
a module file, decorating the name according to the system's
conventions. Added the Windows implementation.
* gmodule/libgplugin_a.c gmodule/libgplugin_b.c:
Added LibMain for LCC-Win32.
* gmodule/testgmodule.c:
Handle Windows dll names.
1998-10-27 05:11:34 +01:00
|
|
|
#include <io.h> /* For _read() */
|
|
|
|
#endif
|
1998-06-11 01:21:14 +02:00
|
|
|
|
|
|
|
/* --- defines --- */
|
|
|
|
#define to_lower(c) ( \
|
|
|
|
(guchar) ( \
|
|
|
|
( (((guchar)(c))>='A' && ((guchar)(c))<='Z') * ('a'-'A') ) | \
|
|
|
|
( (((guchar)(c))>=192 && ((guchar)(c))<=214) * (224-192) ) | \
|
|
|
|
( (((guchar)(c))>=216 && ((guchar)(c))<=222) * (248-216) ) | \
|
|
|
|
((guchar)(c)) \
|
|
|
|
) \
|
|
|
|
)
|
1998-09-25 02:44:38 +02:00
|
|
|
#define READ_BUFFER_SIZE (4000)
|
1998-06-11 01:21:14 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* --- typedefs --- */
|
1998-07-23 00:32:22 +02:00
|
|
|
typedef struct _GScannerKey GScannerKey;
|
1998-06-11 01:21:14 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
struct _GScannerKey
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-07-23 00:32:22 +02:00
|
|
|
guint scope_id;
|
|
|
|
gchar *symbol;
|
|
|
|
gpointer value;
|
1998-06-11 01:21:14 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* --- variables --- */
|
1998-09-25 02:44:38 +02:00
|
|
|
static GScannerConfig g_scanner_config_template =
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
|
|
|
(
|
removed dummy structure definitions for struct _GCache, _GTree, _GTimer,
Tue Oct 27 03:00:50 1998 Tim Janik <timj@gtk.org>
* glib.h: removed dummy structure definitions for struct _GCache,
_GTree, _GTimer, _GMemChunk, _GListAllocator and _GStringChunk.
* gutils.c: implement glib's inline functions _after_ all include
statements have been processed.
removed Tor's MAXPATHLEN check since there already was one supplied
further down in this file.
(LibMain): special cased the #ifdef __LCC__ case for NATIVE_WIN32,
since lcc maybe used on other platforms as well. why in hell is this
stuff required?
(g_get_any_init): for windows, if the user name is supplied, use it as
realname also.
in general, if there is no homedir specified, use the tmpdir that
we already figured.
* gtimer.c (g_timer_elapsed): changed a g_assert() statement to
g_return_if_fail().
* applied glib-tml-981020-0.patch for WIN32 portability, added some
comments and g_return_if_fail() statements, minor indentation fixes.
ChangeLog entry from Tor Lillqvist is appended.
* glib.h (struct dirent): use lower case structure members.
* glib.h:
* makefile.lcc:
* makefile.msc:
s/COMPILING_GLIB/GLIB_COMPILATION/
1998-10-20: Tor Lillqvist <tml@iki.fi>
* README.win32 glib.def gmodule.def
* glibconfig.h.win32 gmodule/gmoduleconf.h.win32:
New files for the Windows port. The .def files list exported
symbols for the Microsoft linker and compatibles.
* configure.in:
Added checks for some platform-dependent headers: pwd.h sys/param.h
sys/select.h sys/time.h sys/times.h unistd.h, and the function lstat.
* gerror.c:
Conditionalized inclusion of system-dependent headers. Changes
for Windows: no gdb to do a stack trace. Just call abort().
* glib.h:
Changes for Windows:
Added macros G_DIR_SEPARATOR, G_DIR_SEPARATOR_S for
platform-dependent file name syntax elements. Added macros
G_SEARCHPATH_SEPARATOR, G_SEARCHPATH_SEPARATOR_S for
platform-dependent search path syntax conventions.
Added pragmas for Microsoft C to make it more pedantic.
Marked GLib's global variables for export from DLL.
Added the function g_strescape that escapes backslashes.
Added functions g_path_is_absolute and g_path_skip_root to
handle platform-dependent file name syntax.
Added the function g_getenv that expands environment variables
that contain references to other environment variables, as is
typical on Windows NT.
Added the GIOChannel structure which is used to encapsulate the
IPC mechanism used by the GIMP's plug-ins, and possibly other
things later. On Unix a GIOChannel encapsulates just a file
descriptor. On Windows it contains a file handle from _pipe() and a
few other things related to the implementation of gdk_input_add
and GIMP plug-in communication. Subject to change.
Removed duplicate declarations of the version variables.
For the Microsoft compiler, declare own implementation of
ftruncate and the <dirent.h> functions.
* gmem.c:
Define a symbolic name for the profiling table size.
* gmessages.c:
Conditionalized inclusion of unistd.h. On Windows, output using
stdio to stdout.
* gscanner.c:
Conditionalized inclusion of unistd.h. Added changes for
Microsoft C. Added CR to the skipped character set. Added small
workaround for MSC compiler bug in g_scanner_cur_value.
* gstrfuncs.c:
Added the function g_strescape, which escapes the backslash
character. Needed especially when printing Windows filenames.
* gtimer.c:
Conditionalized inclusion of unistd.h and sys/time.h. Added
implementations for Windows.
* gutils.c:
Conditionalized inclusion of platform-dependent headers. Use
the platform-independent file name syntax macros.
Conditionalize code on platform-dependent features. Added the
functions g_path_is_absolute g_path_skip_root and g_getenv.
Added the GIOChannel-related functions. Added
compiler-dependent Unix compatibility functions for Windows.
* makefile.lcc makefile.msc:
New files. Compiler-specific makefiles for LCC-Win32 and
Microsoft C. Only Microsoft C is actually supported currently.
* testglib.c:
Added pathname check cases for Windows. Added workaround for
bug in the Microsoft runtime library. Improved some tests a bit.
Tue Oct 27 04:00:11 1998 Tim Janik <timj@gtk.org>
* testgmodule.c (main): changed the #ifdef WIN32 test to NATIVE_WIN32,
this needs to be more constistent throughout the code, do we go for
NATIVE_WIN32 or WIN32?
* gmodule.c (LibMain): special cased the #ifdef __LCC__ case for
NATIVE_WIN32, since lcc maybe used on other platforms as well.
* libgplugin_a.c (LibMain):
* libgplugin_b.c (LibMain):
likewise. not sure i like this special requirement for lcc in here.
* gmodule-dl.c (_g_module_build_path):
feature empty "" directories and prepend the module name with "lib".
* gmodule-dld.c (_g_module_build_path):
* gmodule-win32.c (_g_module_build_path):
feature empty "" directories.
* we need some more magic in the _g_module_build_path variants
so we don't append/prepend lib and .so, .sl or .dll for those names
that already contain it.
* applied patch from Tor Lillqvist for g_module_build_path() and
windows support.
1998-10-20: Tor Lillqvist <tml@iki.fi>
* gmodule/gmodule-win32.c:
New file.
* gmodule/gmodule.c gmodule/gmodule.h:
Added the funcion g_module_build_path that builds the path to
a module file, decorating the name according to the system's
conventions. Added the Windows implementation.
* gmodule/libgplugin_a.c gmodule/libgplugin_b.c:
Added LibMain for LCC-Win32.
* gmodule/testgmodule.c:
Handle Windows dll names.
1998-10-27 05:11:34 +01:00
|
|
|
" \t\r\n"
|
1998-06-11 01:21:14 +02:00
|
|
|
) /* cset_skip_characters */,
|
|
|
|
(
|
|
|
|
G_CSET_a_2_z
|
|
|
|
"_"
|
|
|
|
G_CSET_A_2_Z
|
|
|
|
) /* cset_identifier_first */,
|
|
|
|
(
|
|
|
|
G_CSET_a_2_z
|
2000-05-12 17:23:16 +02:00
|
|
|
"_"
|
1998-06-11 01:21:14 +02:00
|
|
|
G_CSET_A_2_Z
|
2000-05-12 17:23:16 +02:00
|
|
|
G_CSET_DIGITS
|
1998-06-11 01:21:14 +02:00
|
|
|
G_CSET_LATINS
|
|
|
|
G_CSET_LATINC
|
|
|
|
) /* cset_identifier_nth */,
|
|
|
|
( "#\n" ) /* cpair_comment_single */,
|
|
|
|
|
|
|
|
FALSE /* case_sensitive */,
|
|
|
|
|
|
|
|
TRUE /* skip_comment_multi */,
|
|
|
|
TRUE /* skip_comment_single */,
|
|
|
|
TRUE /* scan_comment_multi */,
|
|
|
|
TRUE /* scan_identifier */,
|
|
|
|
FALSE /* scan_identifier_1char */,
|
|
|
|
FALSE /* scan_identifier_NULL */,
|
|
|
|
TRUE /* scan_symbols */,
|
|
|
|
FALSE /* scan_binary */,
|
|
|
|
TRUE /* scan_octal */,
|
|
|
|
TRUE /* scan_float */,
|
|
|
|
TRUE /* scan_hex */,
|
|
|
|
FALSE /* scan_hex_dollar */,
|
|
|
|
TRUE /* scan_string_sq */,
|
|
|
|
TRUE /* scan_string_dq */,
|
|
|
|
TRUE /* numbers_2_int */,
|
|
|
|
FALSE /* int_2_float */,
|
|
|
|
FALSE /* identifier_2_string */,
|
|
|
|
TRUE /* char_2_token */,
|
|
|
|
FALSE /* symbol_2_token */,
|
1998-07-23 00:32:22 +02:00
|
|
|
FALSE /* scope_0_fallback */,
|
1998-06-11 01:21:14 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* --- prototypes --- */
|
1998-07-23 00:32:22 +02:00
|
|
|
static inline
|
|
|
|
GScannerKey* g_scanner_lookup_internal (GScanner *scanner,
|
|
|
|
guint scope_id,
|
|
|
|
const gchar *symbol);
|
Introduced new function type GEqualFunc to return TRUE for equal params.
2000-10-30 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gcache.h, gcache.c, ghash.h, ghash.c, grel.c, grel.h, gtypes.h:
Introduced new function type GEqualFunc to return TRUE for equal
params. This is now used instead of GCompareFunc (which should
work akin to strcmp) here. This kind of fixes Bug #14412. Note
that technically GCompareFunc and GEqualFunc are still the same
types, as gint == gboolean.
* ghash.h, gutils.c: g_int_equal and g_direct_equal now return
gboolean to be really become GEqualFunc.
* gscanner.c, testglib.c, tests/hash-test.c: Some tiny changes to
follow the above change.
2000-10-30 15:34:52 +01:00
|
|
|
static gboolean g_scanner_key_equal (gconstpointer v1,
|
1998-07-23 00:32:22 +02:00
|
|
|
gconstpointer v2);
|
|
|
|
static guint g_scanner_key_hash (gconstpointer v);
|
|
|
|
static void g_scanner_get_token_ll (GScanner *scanner,
|
|
|
|
GTokenType *token_p,
|
1998-09-21 04:32:30 +02:00
|
|
|
GTokenValue *value_p,
|
1998-07-23 00:32:22 +02:00
|
|
|
guint *line_p,
|
|
|
|
guint *position_p);
|
|
|
|
static void g_scanner_get_token_i (GScanner *scanner,
|
|
|
|
GTokenType *token_p,
|
1998-09-21 04:32:30 +02:00
|
|
|
GTokenValue *value_p,
|
1998-07-23 00:32:22 +02:00
|
|
|
guint *line_p,
|
|
|
|
guint *position_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);
|
1998-06-11 01:21:14 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* --- functions --- */
|
1998-09-25 02:44:38 +02:00
|
|
|
static inline gint
|
1998-06-11 01:21:14 +02:00
|
|
|
g_scanner_char_2_num (guchar c,
|
|
|
|
guchar base)
|
|
|
|
{
|
|
|
|
if (c >= '0' && c <= '9')
|
|
|
|
c -= '0';
|
|
|
|
else if (c >= 'A' && c <= 'Z')
|
|
|
|
c -= 'A' - 10;
|
|
|
|
else if (c >= 'a' && c <= 'z')
|
|
|
|
c -= 'a' - 10;
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (c < base)
|
|
|
|
return c;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
GScanner*
|
2001-03-14 16:33:45 +01:00
|
|
|
g_scanner_new (const GScannerConfig *config_templ)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
GScanner *scanner;
|
1998-06-11 01:21:14 +02:00
|
|
|
|
|
|
|
if (!config_templ)
|
|
|
|
config_templ = &g_scanner_config_template;
|
|
|
|
|
|
|
|
scanner = g_new0 (GScanner, 1);
|
|
|
|
|
|
|
|
scanner->user_data = NULL;
|
|
|
|
scanner->max_parse_errors = 0;
|
1998-06-12 16:39:38 +02:00
|
|
|
scanner->parse_errors = 0;
|
|
|
|
scanner->input_name = NULL;
|
2001-03-18 05:44:38 +01:00
|
|
|
g_datalist_init (&scanner->qdata);
|
1998-06-11 01:21:14 +02:00
|
|
|
|
|
|
|
scanner->config = g_new0 (GScannerConfig, 1);
|
|
|
|
|
2001-03-14 16:33:45 +01:00
|
|
|
scanner->config->case_sensitive = config_templ->case_sensitive;
|
|
|
|
scanner->config->cset_skip_characters = config_templ->cset_skip_characters;
|
2000-04-19 08:49:39 +02:00
|
|
|
if (!scanner->config->cset_skip_characters)
|
|
|
|
scanner->config->cset_skip_characters = "";
|
2001-03-14 16:33:45 +01:00
|
|
|
scanner->config->cset_identifier_first = config_templ->cset_identifier_first;
|
|
|
|
scanner->config->cset_identifier_nth = config_templ->cset_identifier_nth;
|
|
|
|
scanner->config->cpair_comment_single = config_templ->cpair_comment_single;
|
|
|
|
scanner->config->skip_comment_multi = config_templ->skip_comment_multi;
|
|
|
|
scanner->config->skip_comment_single = config_templ->skip_comment_single;
|
|
|
|
scanner->config->scan_comment_multi = config_templ->scan_comment_multi;
|
|
|
|
scanner->config->scan_identifier = config_templ->scan_identifier;
|
|
|
|
scanner->config->scan_identifier_1char = config_templ->scan_identifier_1char;
|
|
|
|
scanner->config->scan_identifier_NULL = config_templ->scan_identifier_NULL;
|
|
|
|
scanner->config->scan_symbols = config_templ->scan_symbols;
|
|
|
|
scanner->config->scan_binary = config_templ->scan_binary;
|
|
|
|
scanner->config->scan_octal = config_templ->scan_octal;
|
|
|
|
scanner->config->scan_float = config_templ->scan_float;
|
|
|
|
scanner->config->scan_hex = config_templ->scan_hex;
|
|
|
|
scanner->config->scan_hex_dollar = config_templ->scan_hex_dollar;
|
|
|
|
scanner->config->scan_string_sq = config_templ->scan_string_sq;
|
|
|
|
scanner->config->scan_string_dq = config_templ->scan_string_dq;
|
|
|
|
scanner->config->numbers_2_int = config_templ->numbers_2_int;
|
|
|
|
scanner->config->int_2_float = config_templ->int_2_float;
|
|
|
|
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;
|
1998-06-11 01:21:14 +02:00
|
|
|
|
|
|
|
scanner->token = G_TOKEN_NONE;
|
|
|
|
scanner->value.v_int = 0;
|
|
|
|
scanner->line = 1;
|
|
|
|
scanner->position = 0;
|
|
|
|
|
|
|
|
scanner->next_token = G_TOKEN_NONE;
|
|
|
|
scanner->next_value.v_int = 0;
|
|
|
|
scanner->next_line = 1;
|
|
|
|
scanner->next_position = 0;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
scanner->symbol_table = g_hash_table_new (g_scanner_key_hash, g_scanner_key_equal);
|
1998-06-11 01:21:14 +02:00
|
|
|
scanner->input_fd = -1;
|
1998-09-25 02:44:38 +02:00
|
|
|
scanner->text = NULL;
|
|
|
|
scanner->text_end = NULL;
|
|
|
|
scanner->buffer = NULL;
|
1998-07-23 00:32:22 +02:00
|
|
|
scanner->scope_id = 0;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
scanner->msg_handler = g_scanner_msg_handler;
|
|
|
|
|
|
|
|
return scanner;
|
|
|
|
}
|
|
|
|
|
1998-09-25 02:44:38 +02:00
|
|
|
static inline void
|
|
|
|
g_scanner_free_value (GTokenType *token_p,
|
|
|
|
GTokenValue *value_p)
|
|
|
|
{
|
|
|
|
switch (*token_p)
|
|
|
|
{
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_STRING:
|
|
|
|
case G_TOKEN_IDENTIFIER:
|
|
|
|
case G_TOKEN_IDENTIFIER_NULL:
|
|
|
|
case G_TOKEN_COMMENT_SINGLE:
|
|
|
|
case G_TOKEN_COMMENT_MULTI:
|
1998-09-25 02:44:38 +02:00
|
|
|
g_free (value_p->v_string);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
*token_p = G_TOKEN_NONE;
|
|
|
|
}
|
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
static void
|
1998-07-23 00:32:22 +02:00
|
|
|
g_scanner_destroy_symbol_table_entry (gpointer _key,
|
|
|
|
gpointer _value,
|
|
|
|
gpointer _data)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-07-23 00:32:22 +02:00
|
|
|
GScannerKey *key = _key;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
g_free (key->symbol);
|
1998-06-11 01:21:14 +02:00
|
|
|
g_free (key);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
g_scanner_destroy (GScanner *scanner)
|
|
|
|
{
|
|
|
|
g_return_if_fail (scanner != NULL);
|
|
|
|
|
2001-03-18 05:44:38 +01:00
|
|
|
g_datalist_clear (&scanner->qdata);
|
1998-06-11 01:21:14 +02:00
|
|
|
g_hash_table_foreach (scanner->symbol_table,
|
1998-07-23 00:32:22 +02:00
|
|
|
g_scanner_destroy_symbol_table_entry, NULL);
|
1998-06-11 01:21:14 +02:00
|
|
|
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);
|
|
|
|
g_free (scanner->config);
|
1998-09-25 02:44:38 +02:00
|
|
|
g_free (scanner->buffer);
|
1998-06-11 01:21:14 +02:00
|
|
|
g_free (scanner);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1998-07-23 00:32:22 +02:00
|
|
|
g_scanner_msg_handler (GScanner *scanner,
|
1998-06-11 01:21:14 +02:00
|
|
|
gchar *message,
|
|
|
|
gint is_error)
|
|
|
|
{
|
|
|
|
g_return_if_fail (scanner != NULL);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
fprintf (stdout, "%s:%d: ", scanner->input_name, scanner->line);
|
|
|
|
if (is_error)
|
|
|
|
fprintf (stdout, "error: ");
|
|
|
|
fprintf (stdout, "%s\n", message);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1998-07-23 00:32:22 +02:00
|
|
|
g_scanner_error (GScanner *scanner,
|
|
|
|
const gchar *format,
|
1998-06-11 01:21:14 +02:00
|
|
|
...)
|
|
|
|
{
|
|
|
|
g_return_if_fail (scanner != NULL);
|
|
|
|
g_return_if_fail (format != NULL);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
scanner->parse_errors++;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
if (scanner->msg_handler)
|
|
|
|
{
|
removed this function which was not publically exported in glib.h. to
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-24 07:26:53 +02:00
|
|
|
va_list args;
|
1998-06-11 01:21:14 +02:00
|
|
|
gchar *string;
|
|
|
|
|
|
|
|
va_start (args, format);
|
removed this function which was not publically exported in glib.h. to
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-24 07:26:53 +02:00
|
|
|
string = g_strdup_vprintf (format, args);
|
1998-06-11 01:21:14 +02:00
|
|
|
va_end (args);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
scanner->msg_handler (scanner, string, TRUE);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
g_free (string);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
g_scanner_warn (GScanner *scanner,
|
|
|
|
const gchar *format,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
g_return_if_fail (scanner != NULL);
|
|
|
|
g_return_if_fail (format != NULL);
|
|
|
|
|
|
|
|
if (scanner->msg_handler)
|
|
|
|
{
|
removed this function which was not publically exported in glib.h. to
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-24 07:26:53 +02:00
|
|
|
va_list args;
|
1998-06-11 01:21:14 +02:00
|
|
|
gchar *string;
|
|
|
|
|
|
|
|
va_start (args, format);
|
removed this function which was not publically exported in glib.h. to
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-24 07:26:53 +02:00
|
|
|
string = g_strdup_vprintf (format, args);
|
1998-06-11 01:21:14 +02:00
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
scanner->msg_handler (scanner, string, FALSE);
|
|
|
|
|
|
|
|
g_free (string);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Introduced new function type GEqualFunc to return TRUE for equal params.
2000-10-30 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gcache.h, gcache.c, ghash.h, ghash.c, grel.c, grel.h, gtypes.h:
Introduced new function type GEqualFunc to return TRUE for equal
params. This is now used instead of GCompareFunc (which should
work akin to strcmp) here. This kind of fixes Bug #14412. Note
that technically GCompareFunc and GEqualFunc are still the same
types, as gint == gboolean.
* ghash.h, gutils.c: g_int_equal and g_direct_equal now return
gboolean to be really become GEqualFunc.
* gscanner.c, testglib.c, tests/hash-test.c: Some tiny changes to
follow the above change.
2000-10-30 15:34:52 +01:00
|
|
|
static gboolean
|
1998-07-23 00:32:22 +02:00
|
|
|
g_scanner_key_equal (gconstpointer v1,
|
|
|
|
gconstpointer v2)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
const GScannerKey *key1 = v1;
|
|
|
|
const GScannerKey *key2 = v2;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
return (key1->scope_id == key2->scope_id) && (strcmp (key1->symbol, key2->symbol) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static guint
|
|
|
|
g_scanner_key_hash (gconstpointer v)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
const GScannerKey *key = v;
|
|
|
|
gchar *c;
|
|
|
|
guint h;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
h = key->scope_id;
|
|
|
|
for (c = key->symbol; *c; c++)
|
2001-05-10 15:58:40 +02:00
|
|
|
h = (h << 5) - h + *c;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline GScannerKey*
|
|
|
|
g_scanner_lookup_internal (GScanner *scanner,
|
|
|
|
guint scope_id,
|
|
|
|
const gchar *symbol)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
GScannerKey *key_p;
|
1998-07-23 00:32:22 +02:00
|
|
|
GScannerKey key;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
key.scope_id = scope_id;
|
|
|
|
|
|
|
|
if (!scanner->config->case_sensitive)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
gchar *d;
|
|
|
|
const gchar *c;
|
1998-07-23 00:32:22 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
void
|
1998-07-23 00:32:22 +02:00
|
|
|
g_scanner_scope_add_symbol (GScanner *scanner,
|
|
|
|
guint scope_id,
|
|
|
|
const gchar *symbol,
|
|
|
|
gpointer value)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
GScannerKey *key;
|
1998-06-11 01:21:14 +02:00
|
|
|
|
|
|
|
g_return_if_fail (scanner != NULL);
|
|
|
|
g_return_if_fail (symbol != NULL);
|
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
key = g_scanner_lookup_internal (scanner, scope_id, symbol);
|
1998-06-11 01:21:14 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
if (!key)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-07-23 00:32:22 +02:00
|
|
|
key = g_new (GScannerKey, 1);
|
|
|
|
key->scope_id = scope_id;
|
|
|
|
key->symbol = g_strdup (symbol);
|
|
|
|
key->value = value;
|
1998-06-11 01:21:14 +02:00
|
|
|
if (!scanner->config->case_sensitive)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
gchar *c;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
c = key->symbol;
|
|
|
|
while (*c != 0)
|
|
|
|
{
|
|
|
|
*c = to_lower (*c);
|
|
|
|
c++;
|
|
|
|
}
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
1998-07-23 00:32:22 +02:00
|
|
|
g_hash_table_insert (scanner->symbol_table, key, key);
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
else
|
1998-07-23 00:32:22 +02:00
|
|
|
key->value = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
g_scanner_scope_remove_symbol (GScanner *scanner,
|
|
|
|
guint scope_id,
|
|
|
|
const gchar *symbol)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
GScannerKey *key;
|
1998-07-23 00:32:22 +02:00
|
|
|
|
|
|
|
g_return_if_fail (scanner != NULL);
|
|
|
|
g_return_if_fail (symbol != NULL);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
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);
|
|
|
|
}
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
gpointer
|
|
|
|
g_scanner_lookup_symbol (GScanner *scanner,
|
|
|
|
const gchar *symbol)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
GScannerKey *key;
|
|
|
|
guint scope_id;
|
1998-07-23 00:32:22 +02:00
|
|
|
|
|
|
|
g_return_val_if_fail (scanner != NULL, NULL);
|
|
|
|
|
|
|
|
if (!symbol)
|
|
|
|
return NULL;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
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)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
GScannerKey *key;
|
1998-06-11 01:21:14 +02:00
|
|
|
|
|
|
|
g_return_val_if_fail (scanner != NULL, NULL);
|
|
|
|
|
|
|
|
if (!symbol)
|
|
|
|
return NULL;
|
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
key = g_scanner_lookup_internal (scanner, scope_id, symbol);
|
1998-06-11 01:21:14 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
if (key)
|
|
|
|
return key->value;
|
1998-06-11 01:21:14 +02:00
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
guint
|
|
|
|
g_scanner_set_scope (GScanner *scanner,
|
|
|
|
guint scope_id)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
guint old_scope_id;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
g_return_val_if_fail (scanner != NULL, 0);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
old_scope_id = scanner->scope_id;
|
|
|
|
scanner->scope_id = scope_id;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
return old_scope_id;
|
|
|
|
}
|
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
static void
|
1998-07-23 00:32:22 +02:00
|
|
|
g_scanner_foreach_internal (gpointer _key,
|
|
|
|
gpointer _value,
|
|
|
|
gpointer _user_data)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
GScannerKey *key;
|
|
|
|
gpointer *d;
|
|
|
|
GHFunc func;
|
|
|
|
gpointer user_data;
|
|
|
|
guint *scope_id;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
d = _user_data;
|
|
|
|
func = (GHFunc) d[0];
|
1998-12-16 15:41:18 +01:00
|
|
|
user_data = d[1];
|
1998-07-23 00:32:22 +02:00
|
|
|
scope_id = d[2];
|
|
|
|
key = _value;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
if (key->scope_id == *scope_id)
|
1998-12-16 15:41:18 +01:00
|
|
|
func (key->symbol, key->value, user_data);
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1998-07-23 00:32:22 +02:00
|
|
|
g_scanner_scope_foreach_symbol (GScanner *scanner,
|
|
|
|
guint scope_id,
|
|
|
|
GHFunc func,
|
1998-12-16 15:41:18 +01:00
|
|
|
gpointer user_data)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-07-23 00:32:22 +02:00
|
|
|
gpointer d[3];
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
g_return_if_fail (scanner != NULL);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
d[0] = (gpointer) func;
|
1998-12-16 15:41:18 +01:00
|
|
|
d[1] = user_data;
|
1998-07-23 00:32:22 +02:00
|
|
|
d[2] = &scope_id;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
g_hash_table_foreach (scanner->symbol_table, g_scanner_foreach_internal, d);
|
|
|
|
}
|
|
|
|
|
|
|
|
GTokenType
|
|
|
|
g_scanner_peek_next_token (GScanner *scanner)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
|
|
|
|
|
|
|
|
if (scanner->next_token == G_TOKEN_NONE)
|
|
|
|
{
|
|
|
|
scanner->next_line = scanner->line;
|
|
|
|
scanner->next_position = scanner->position;
|
|
|
|
g_scanner_get_token_i (scanner,
|
|
|
|
&scanner->next_token,
|
|
|
|
&scanner->next_value,
|
|
|
|
&scanner->next_line,
|
|
|
|
&scanner->next_position);
|
|
|
|
}
|
|
|
|
|
|
|
|
return scanner->next_token;
|
|
|
|
}
|
|
|
|
|
|
|
|
GTokenType
|
|
|
|
g_scanner_get_next_token (GScanner *scanner)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
|
|
|
|
|
|
|
|
if (scanner->next_token != G_TOKEN_NONE)
|
|
|
|
{
|
|
|
|
g_scanner_free_value (&scanner->token, &scanner->value);
|
|
|
|
|
|
|
|
scanner->token = scanner->next_token;
|
|
|
|
scanner->value = scanner->next_value;
|
|
|
|
scanner->line = scanner->next_line;
|
|
|
|
scanner->position = scanner->next_position;
|
|
|
|
scanner->next_token = G_TOKEN_NONE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_scanner_get_token_i (scanner,
|
|
|
|
&scanner->token,
|
|
|
|
&scanner->value,
|
|
|
|
&scanner->line,
|
|
|
|
&scanner->position);
|
|
|
|
|
|
|
|
return scanner->token;
|
|
|
|
}
|
|
|
|
|
|
|
|
GTokenType
|
|
|
|
g_scanner_cur_token (GScanner *scanner)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
|
|
|
|
|
|
|
|
return scanner->token;
|
|
|
|
}
|
|
|
|
|
1998-09-21 04:32:30 +02:00
|
|
|
GTokenValue
|
1998-06-11 01:21:14 +02:00
|
|
|
g_scanner_cur_value (GScanner *scanner)
|
|
|
|
{
|
1998-09-21 04:32:30 +02:00
|
|
|
GTokenValue v;
|
1998-06-11 01:21:14 +02:00
|
|
|
|
1998-11-25 04:02:56 +01:00
|
|
|
v.v_int = 0;
|
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
g_return_val_if_fail (scanner != NULL, v);
|
removed dummy structure definitions for struct _GCache, _GTree, _GTimer,
Tue Oct 27 03:00:50 1998 Tim Janik <timj@gtk.org>
* glib.h: removed dummy structure definitions for struct _GCache,
_GTree, _GTimer, _GMemChunk, _GListAllocator and _GStringChunk.
* gutils.c: implement glib's inline functions _after_ all include
statements have been processed.
removed Tor's MAXPATHLEN check since there already was one supplied
further down in this file.
(LibMain): special cased the #ifdef __LCC__ case for NATIVE_WIN32,
since lcc maybe used on other platforms as well. why in hell is this
stuff required?
(g_get_any_init): for windows, if the user name is supplied, use it as
realname also.
in general, if there is no homedir specified, use the tmpdir that
we already figured.
* gtimer.c (g_timer_elapsed): changed a g_assert() statement to
g_return_if_fail().
* applied glib-tml-981020-0.patch for WIN32 portability, added some
comments and g_return_if_fail() statements, minor indentation fixes.
ChangeLog entry from Tor Lillqvist is appended.
* glib.h (struct dirent): use lower case structure members.
* glib.h:
* makefile.lcc:
* makefile.msc:
s/COMPILING_GLIB/GLIB_COMPILATION/
1998-10-20: Tor Lillqvist <tml@iki.fi>
* README.win32 glib.def gmodule.def
* glibconfig.h.win32 gmodule/gmoduleconf.h.win32:
New files for the Windows port. The .def files list exported
symbols for the Microsoft linker and compatibles.
* configure.in:
Added checks for some platform-dependent headers: pwd.h sys/param.h
sys/select.h sys/time.h sys/times.h unistd.h, and the function lstat.
* gerror.c:
Conditionalized inclusion of system-dependent headers. Changes
for Windows: no gdb to do a stack trace. Just call abort().
* glib.h:
Changes for Windows:
Added macros G_DIR_SEPARATOR, G_DIR_SEPARATOR_S for
platform-dependent file name syntax elements. Added macros
G_SEARCHPATH_SEPARATOR, G_SEARCHPATH_SEPARATOR_S for
platform-dependent search path syntax conventions.
Added pragmas for Microsoft C to make it more pedantic.
Marked GLib's global variables for export from DLL.
Added the function g_strescape that escapes backslashes.
Added functions g_path_is_absolute and g_path_skip_root to
handle platform-dependent file name syntax.
Added the function g_getenv that expands environment variables
that contain references to other environment variables, as is
typical on Windows NT.
Added the GIOChannel structure which is used to encapsulate the
IPC mechanism used by the GIMP's plug-ins, and possibly other
things later. On Unix a GIOChannel encapsulates just a file
descriptor. On Windows it contains a file handle from _pipe() and a
few other things related to the implementation of gdk_input_add
and GIMP plug-in communication. Subject to change.
Removed duplicate declarations of the version variables.
For the Microsoft compiler, declare own implementation of
ftruncate and the <dirent.h> functions.
* gmem.c:
Define a symbolic name for the profiling table size.
* gmessages.c:
Conditionalized inclusion of unistd.h. On Windows, output using
stdio to stdout.
* gscanner.c:
Conditionalized inclusion of unistd.h. Added changes for
Microsoft C. Added CR to the skipped character set. Added small
workaround for MSC compiler bug in g_scanner_cur_value.
* gstrfuncs.c:
Added the function g_strescape, which escapes the backslash
character. Needed especially when printing Windows filenames.
* gtimer.c:
Conditionalized inclusion of unistd.h and sys/time.h. Added
implementations for Windows.
* gutils.c:
Conditionalized inclusion of platform-dependent headers. Use
the platform-independent file name syntax macros.
Conditionalize code on platform-dependent features. Added the
functions g_path_is_absolute g_path_skip_root and g_getenv.
Added the GIOChannel-related functions. Added
compiler-dependent Unix compatibility functions for Windows.
* makefile.lcc makefile.msc:
New files. Compiler-specific makefiles for LCC-Win32 and
Microsoft C. Only Microsoft C is actually supported currently.
* testglib.c:
Added pathname check cases for Windows. Added workaround for
bug in the Microsoft runtime library. Improved some tests a bit.
Tue Oct 27 04:00:11 1998 Tim Janik <timj@gtk.org>
* testgmodule.c (main): changed the #ifdef WIN32 test to NATIVE_WIN32,
this needs to be more constistent throughout the code, do we go for
NATIVE_WIN32 or WIN32?
* gmodule.c (LibMain): special cased the #ifdef __LCC__ case for
NATIVE_WIN32, since lcc maybe used on other platforms as well.
* libgplugin_a.c (LibMain):
* libgplugin_b.c (LibMain):
likewise. not sure i like this special requirement for lcc in here.
* gmodule-dl.c (_g_module_build_path):
feature empty "" directories and prepend the module name with "lib".
* gmodule-dld.c (_g_module_build_path):
* gmodule-win32.c (_g_module_build_path):
feature empty "" directories.
* we need some more magic in the _g_module_build_path variants
so we don't append/prepend lib and .so, .sl or .dll for those names
that already contain it.
* applied patch from Tor Lillqvist for g_module_build_path() and
windows support.
1998-10-20: Tor Lillqvist <tml@iki.fi>
* gmodule/gmodule-win32.c:
New file.
* gmodule/gmodule.c gmodule/gmodule.h:
Added the funcion g_module_build_path that builds the path to
a module file, decorating the name according to the system's
conventions. Added the Windows implementation.
* gmodule/libgplugin_a.c gmodule/libgplugin_b.c:
Added LibMain for LCC-Win32.
* gmodule/testgmodule.c:
Handle Windows dll names.
1998-10-27 05:11:34 +01:00
|
|
|
|
|
|
|
/* MSC isn't capable of handling return scanner->value; ? */
|
|
|
|
|
|
|
|
v = scanner->value;
|
|
|
|
|
|
|
|
return v;
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
guint
|
|
|
|
g_scanner_cur_line (GScanner *scanner)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (scanner != NULL, 0);
|
|
|
|
|
|
|
|
return scanner->line;
|
|
|
|
}
|
|
|
|
|
|
|
|
guint
|
|
|
|
g_scanner_cur_position (GScanner *scanner)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (scanner != NULL, 0);
|
|
|
|
|
|
|
|
return scanner->position;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
g_scanner_eof (GScanner *scanner)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (scanner != NULL, TRUE);
|
|
|
|
|
|
|
|
return scanner->token == G_TOKEN_EOF;
|
|
|
|
}
|
|
|
|
|
1998-09-25 02:44:38 +02:00
|
|
|
void
|
|
|
|
g_scanner_input_file (GScanner *scanner,
|
|
|
|
gint input_fd)
|
|
|
|
{
|
|
|
|
g_return_if_fail (scanner != NULL);
|
|
|
|
g_return_if_fail (input_fd >= 0);
|
|
|
|
|
1998-10-28 02:32:54 +01:00
|
|
|
if (scanner->input_fd >= 0)
|
|
|
|
g_scanner_sync_file_offset (scanner);
|
|
|
|
|
1998-09-25 02:44:38 +02:00
|
|
|
scanner->token = G_TOKEN_NONE;
|
|
|
|
scanner->value.v_int = 0;
|
|
|
|
scanner->line = 1;
|
|
|
|
scanner->position = 0;
|
|
|
|
scanner->next_token = G_TOKEN_NONE;
|
|
|
|
|
|
|
|
scanner->input_fd = input_fd;
|
|
|
|
scanner->text = NULL;
|
|
|
|
scanner->text_end = NULL;
|
|
|
|
|
|
|
|
if (!scanner->buffer)
|
|
|
|
scanner->buffer = g_new (gchar, READ_BUFFER_SIZE + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
g_scanner_input_text (GScanner *scanner,
|
|
|
|
const gchar *text,
|
|
|
|
guint text_len)
|
|
|
|
{
|
|
|
|
g_return_if_fail (scanner != NULL);
|
|
|
|
if (text_len)
|
|
|
|
g_return_if_fail (text != NULL);
|
|
|
|
else
|
|
|
|
text = NULL;
|
|
|
|
|
1998-10-28 02:32:54 +01:00
|
|
|
if (scanner->input_fd >= 0)
|
|
|
|
g_scanner_sync_file_offset (scanner);
|
|
|
|
|
1998-09-25 02:44:38 +02:00
|
|
|
scanner->token = G_TOKEN_NONE;
|
|
|
|
scanner->value.v_int = 0;
|
|
|
|
scanner->line = 1;
|
|
|
|
scanner->position = 0;
|
|
|
|
scanner->next_token = G_TOKEN_NONE;
|
|
|
|
|
|
|
|
scanner->input_fd = -1;
|
|
|
|
scanner->text = text;
|
|
|
|
scanner->text_end = text + text_len;
|
|
|
|
|
|
|
|
if (scanner->buffer)
|
|
|
|
{
|
|
|
|
g_free (scanner->buffer);
|
|
|
|
scanner->buffer = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
static guchar
|
|
|
|
g_scanner_peek_next_char (GScanner *scanner)
|
|
|
|
{
|
1998-09-25 02:44:38 +02:00
|
|
|
if (scanner->text < scanner->text_end)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-09-25 02:44:38 +02:00
|
|
|
return *scanner->text;
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
else if (scanner->input_fd >= 0)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
gint count;
|
|
|
|
gchar *buffer;
|
1998-09-25 02:44:38 +02:00
|
|
|
|
|
|
|
buffer = scanner->buffer;
|
|
|
|
do
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-09-25 02:44:38 +02:00
|
|
|
count = read (scanner->input_fd, buffer, READ_BUFFER_SIZE);
|
|
|
|
}
|
|
|
|
while (count == -1 && (errno == EINTR || errno == EAGAIN));
|
|
|
|
|
1998-10-25 07:44:49 +01:00
|
|
|
if (count < 1)
|
1998-09-25 02:44:38 +02:00
|
|
|
{
|
|
|
|
scanner->input_fd = -1;
|
|
|
|
|
|
|
|
return 0;
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
else
|
1998-09-25 02:44:38 +02:00
|
|
|
{
|
|
|
|
scanner->text = buffer;
|
|
|
|
scanner->text_end = buffer + count;
|
|
|
|
|
|
|
|
return *buffer;
|
|
|
|
}
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
else
|
1998-09-25 02:44:38 +02:00
|
|
|
return 0;
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
|
1998-10-28 02:32:54 +01:00
|
|
|
void
|
|
|
|
g_scanner_sync_file_offset (GScanner *scanner)
|
|
|
|
{
|
|
|
|
g_return_if_fail (scanner != NULL);
|
|
|
|
|
|
|
|
/* for file input, rewind the filedescriptor to the current
|
|
|
|
* buffer position and blow the file read ahead buffer. usefull for
|
|
|
|
* third party uses of our filedescriptor, which hooks onto the current
|
|
|
|
* scanning position.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (scanner->input_fd >= 0 && scanner->text_end > scanner->text)
|
|
|
|
{
|
|
|
|
gint buffered;
|
|
|
|
|
|
|
|
buffered = scanner->text_end - scanner->text;
|
|
|
|
if (lseek (scanner->input_fd, - buffered, SEEK_CUR) >= 0)
|
|
|
|
{
|
|
|
|
/* we succeeded, blow our buffer's contents now */
|
|
|
|
scanner->text = NULL;
|
|
|
|
scanner->text_end = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
errno = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
static guchar
|
|
|
|
g_scanner_get_char (GScanner *scanner,
|
|
|
|
guint *line_p,
|
|
|
|
guint *position_p)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
guchar fchar;
|
1998-09-25 02:44:38 +02:00
|
|
|
|
|
|
|
if (scanner->text < scanner->text_end)
|
|
|
|
fchar = *(scanner->text++);
|
1998-06-11 01:21:14 +02:00
|
|
|
else if (scanner->input_fd >= 0)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
gint count;
|
|
|
|
gchar *buffer;
|
1998-09-25 02:44:38 +02:00
|
|
|
|
|
|
|
buffer = scanner->buffer;
|
|
|
|
do
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-09-25 02:44:38 +02:00
|
|
|
count = read (scanner->input_fd, buffer, READ_BUFFER_SIZE);
|
|
|
|
}
|
|
|
|
while (count == -1 && (errno == EINTR || errno == EAGAIN));
|
|
|
|
|
1998-10-25 07:44:49 +01:00
|
|
|
if (count < 1)
|
1998-09-25 02:44:38 +02:00
|
|
|
{
|
|
|
|
scanner->input_fd = -1;
|
|
|
|
fchar = 0;
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1998-09-25 02:44:38 +02:00
|
|
|
scanner->text = buffer + 1;
|
|
|
|
scanner->text_end = buffer + count;
|
|
|
|
fchar = *buffer;
|
1998-10-28 02:32:54 +01:00
|
|
|
if (!fchar)
|
|
|
|
{
|
|
|
|
g_scanner_sync_file_offset (scanner);
|
|
|
|
scanner->text_end = scanner->text;
|
|
|
|
scanner->input_fd = -1;
|
|
|
|
}
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fchar = 0;
|
|
|
|
|
|
|
|
if (fchar == '\n')
|
|
|
|
{
|
|
|
|
(*position_p) = 0;
|
|
|
|
(*line_p)++;
|
|
|
|
}
|
|
|
|
else if (fchar)
|
|
|
|
{
|
|
|
|
(*position_p)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fchar;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
g_scanner_unexp_token (GScanner *scanner,
|
|
|
|
GTokenType expected_token,
|
|
|
|
const gchar *identifier_spec,
|
|
|
|
const gchar *symbol_spec,
|
|
|
|
const gchar *symbol_name,
|
|
|
|
const gchar *message,
|
|
|
|
gint is_error)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
gchar *token_string;
|
|
|
|
guint token_string_len;
|
|
|
|
gchar *expected_string;
|
|
|
|
guint expected_string_len;
|
|
|
|
gchar *message_prefix;
|
|
|
|
gboolean print_unexp;
|
1998-07-23 00:32:22 +02:00
|
|
|
void (*msg_handler) (GScanner*, const gchar*, ...);
|
1998-06-11 01:21:14 +02:00
|
|
|
|
|
|
|
g_return_if_fail (scanner != NULL);
|
1998-06-30 13:04:49 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
if (is_error)
|
|
|
|
msg_handler = g_scanner_error;
|
|
|
|
else
|
|
|
|
msg_handler = g_scanner_warn;
|
1998-06-30 13:04:49 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
if (!identifier_spec)
|
|
|
|
identifier_spec = "identifier";
|
|
|
|
if (!symbol_spec)
|
|
|
|
symbol_spec = "symbol";
|
|
|
|
|
|
|
|
token_string_len = 56;
|
|
|
|
token_string = g_new (gchar, token_string_len + 1);
|
|
|
|
expected_string_len = 64;
|
|
|
|
expected_string = g_new (gchar, expected_string_len + 1);
|
|
|
|
print_unexp = TRUE;
|
|
|
|
|
|
|
|
switch (scanner->token)
|
|
|
|
{
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_EOF:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string, token_string_len, "end of file");
|
|
|
|
break;
|
|
|
|
|
1998-06-30 13:04:49 +02:00
|
|
|
default:
|
1998-06-11 01:21:14 +02:00
|
|
|
if (scanner->token >= 1 && scanner->token <= 255)
|
|
|
|
{
|
|
|
|
if ((scanner->token >= ' ' && scanner->token <= '~') ||
|
|
|
|
strchr (scanner->config->cset_identifier_first, scanner->token) ||
|
|
|
|
strchr (scanner->config->cset_identifier_nth, scanner->token))
|
|
|
|
g_snprintf (token_string, expected_string_len, "character `%c'", scanner->token);
|
|
|
|
else
|
|
|
|
g_snprintf (token_string, expected_string_len, "character `\\%o'", scanner->token);
|
1998-06-30 13:04:49 +02:00
|
|
|
break;
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
1998-06-30 13:04:49 +02:00
|
|
|
else if (!scanner->config->symbol_2_token)
|
|
|
|
{
|
|
|
|
g_snprintf (token_string, token_string_len, "(unknown) token <%d>", scanner->token);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* fall through */
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_SYMBOL:
|
1998-06-30 13:04:49 +02:00
|
|
|
if (expected_token == G_TOKEN_SYMBOL ||
|
|
|
|
(scanner->config->symbol_2_token &&
|
|
|
|
expected_token > G_TOKEN_LAST))
|
|
|
|
print_unexp = FALSE;
|
|
|
|
if (symbol_name)
|
|
|
|
g_snprintf (token_string,
|
|
|
|
token_string_len,
|
|
|
|
"%s%s `%s'",
|
|
|
|
print_unexp ? "" : "invalid ",
|
|
|
|
symbol_spec,
|
|
|
|
symbol_name);
|
1998-06-11 01:21:14 +02:00
|
|
|
else
|
1998-06-30 13:04:49 +02:00
|
|
|
g_snprintf (token_string,
|
|
|
|
token_string_len,
|
|
|
|
"%s%s",
|
|
|
|
print_unexp ? "" : "invalid ",
|
|
|
|
symbol_spec);
|
1998-06-11 01:21:14 +02:00
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_ERROR:
|
1998-06-11 01:21:14 +02:00
|
|
|
print_unexp = FALSE;
|
|
|
|
expected_token = G_TOKEN_NONE;
|
|
|
|
switch (scanner->value.v_error)
|
|
|
|
{
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_ERR_UNEXP_EOF:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string, token_string_len, "scanner: unexpected end of file");
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_ERR_UNEXP_EOF_IN_STRING:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string, token_string_len, "scanner: unterminated string constant");
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_ERR_UNEXP_EOF_IN_COMMENT:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string, token_string_len, "scanner: unterminated comment");
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_ERR_NON_DIGIT_IN_CONST:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string, token_string_len, "scanner: non digit in constant");
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_ERR_FLOAT_RADIX:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string, token_string_len, "scanner: invalid radix for floating constant");
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_ERR_FLOAT_MALFORMED:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string, token_string_len, "scanner: malformed floating constant");
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_ERR_DIGIT_RADIX:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string, token_string_len, "scanner: digit is beyond radix");
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_ERR_UNKNOWN:
|
1998-06-11 01:21:14 +02:00
|
|
|
default:
|
|
|
|
g_snprintf (token_string, token_string_len, "scanner: unknown error");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_CHAR:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string, token_string_len, "character `%c'", scanner->value.v_char);
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_IDENTIFIER:
|
|
|
|
case G_TOKEN_IDENTIFIER_NULL:
|
|
|
|
if (expected_token == G_TOKEN_IDENTIFIER ||
|
|
|
|
expected_token == G_TOKEN_IDENTIFIER_NULL)
|
1998-06-11 01:21:14 +02:00
|
|
|
print_unexp = FALSE;
|
|
|
|
g_snprintf (token_string,
|
1998-06-30 13:04:49 +02:00
|
|
|
token_string_len,
|
|
|
|
"%s%s `%s'",
|
|
|
|
print_unexp ? "" : "invalid ",
|
|
|
|
identifier_spec,
|
1999-07-24 20:50:58 +02:00
|
|
|
scanner->token == G_TOKEN_IDENTIFIER ? scanner->value.v_string : "null");
|
1998-06-11 01:21:14 +02:00
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_BINARY:
|
|
|
|
case G_TOKEN_OCTAL:
|
|
|
|
case G_TOKEN_INT:
|
|
|
|
case G_TOKEN_HEX:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string, token_string_len, "number `%ld'", scanner->value.v_int);
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_FLOAT:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string, token_string_len, "number `%.3f'", scanner->value.v_float);
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_STRING:
|
1998-06-30 13:04:49 +02:00
|
|
|
if (expected_token == G_TOKEN_STRING)
|
|
|
|
print_unexp = FALSE;
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string,
|
1998-06-30 13:04:49 +02:00
|
|
|
token_string_len,
|
|
|
|
"%s%sstring constant \"%s\"",
|
|
|
|
print_unexp ? "" : "invalid ",
|
|
|
|
scanner->value.v_string[0] == 0 ? "empty " : "",
|
|
|
|
scanner->value.v_string);
|
1998-06-11 01:21:14 +02:00
|
|
|
token_string[token_string_len - 2] = '"';
|
|
|
|
token_string[token_string_len - 1] = 0;
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_COMMENT_SINGLE:
|
|
|
|
case G_TOKEN_COMMENT_MULTI:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (token_string, token_string_len, "comment");
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_NONE:
|
1998-06-30 13:04:49 +02:00
|
|
|
/* somehow the user's parsing code is screwed, there isn't much
|
|
|
|
* we can do about it.
|
|
|
|
* Note, a common case to trigger this is
|
|
|
|
* g_scanner_peek_next_token(); g_scanner_unexp_token();
|
|
|
|
* without an intermediate g_scanner_get_next_token().
|
|
|
|
*/
|
1998-06-11 01:21:14 +02:00
|
|
|
g_assert_not_reached ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (expected_token)
|
|
|
|
{
|
1998-06-30 13:04:49 +02:00
|
|
|
gboolean need_valid;
|
|
|
|
|
|
|
|
default:
|
1998-06-11 01:21:14 +02:00
|
|
|
if (expected_token >= 1 && expected_token <= 255)
|
|
|
|
{
|
|
|
|
if ((expected_token >= ' ' && expected_token <= '~') ||
|
|
|
|
strchr (scanner->config->cset_identifier_first, expected_token) ||
|
|
|
|
strchr (scanner->config->cset_identifier_nth, expected_token))
|
|
|
|
g_snprintf (expected_string, expected_string_len, "character `%c'", expected_token);
|
|
|
|
else
|
|
|
|
g_snprintf (expected_string, expected_string_len, "character `\\%o'", expected_token);
|
1998-06-30 13:04:49 +02:00
|
|
|
break;
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
1998-06-30 13:04:49 +02:00
|
|
|
else if (!scanner->config->symbol_2_token)
|
|
|
|
{
|
|
|
|
g_snprintf (expected_string, expected_string_len, "(unknown) token <%d>", expected_token);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* fall through */
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_SYMBOL:
|
1998-06-30 13:04:49 +02:00
|
|
|
need_valid = (scanner->token == G_TOKEN_SYMBOL ||
|
|
|
|
(scanner->config->symbol_2_token &&
|
|
|
|
scanner->token > G_TOKEN_LAST));
|
|
|
|
g_snprintf (expected_string,
|
|
|
|
expected_string_len,
|
|
|
|
"%s%s",
|
|
|
|
need_valid ? "valid " : "",
|
|
|
|
symbol_spec);
|
|
|
|
/* FIXME: should we attempt to lookup the symbol_name for symbol_2_token? */
|
1998-06-11 01:21:14 +02:00
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_INT:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (expected_string, expected_string_len, "number (integer)");
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_FLOAT:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (expected_string, expected_string_len, "number (float)");
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_STRING:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (expected_string,
|
1998-06-30 13:04:49 +02:00
|
|
|
expected_string_len,
|
|
|
|
"%sstring constant",
|
|
|
|
scanner->token == G_TOKEN_STRING ? "valid " : "");
|
1998-06-11 01:21:14 +02:00
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_IDENTIFIER:
|
|
|
|
case G_TOKEN_IDENTIFIER_NULL:
|
1998-06-11 01:21:14 +02:00
|
|
|
g_snprintf (expected_string,
|
1998-06-30 13:04:49 +02:00
|
|
|
expected_string_len,
|
|
|
|
"%s%s",
|
1999-01-02 02:32:37 +01:00
|
|
|
(scanner->token == G_TOKEN_IDENTIFIER_NULL ||
|
|
|
|
scanner->token == G_TOKEN_IDENTIFIER ? "valid " : ""),
|
1998-06-30 13:04:49 +02:00
|
|
|
identifier_spec);
|
1998-06-11 01:21:14 +02:00
|
|
|
break;
|
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
case G_TOKEN_EOF:
|
|
|
|
g_snprintf (expected_string, expected_string_len, "end of file");
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case G_TOKEN_NONE:
|
1998-06-11 01:21:14 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (message && message[0] != 0)
|
|
|
|
message_prefix = " - ";
|
|
|
|
else
|
|
|
|
{
|
|
|
|
message_prefix = "";
|
|
|
|
message = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (expected_token != G_TOKEN_NONE)
|
|
|
|
{
|
|
|
|
if (print_unexp)
|
|
|
|
msg_handler (scanner,
|
|
|
|
"unexpected %s, expected %s%s%s",
|
|
|
|
token_string,
|
|
|
|
expected_string,
|
|
|
|
message_prefix,
|
|
|
|
message);
|
|
|
|
else
|
|
|
|
msg_handler (scanner,
|
|
|
|
"%s, expected %s%s%s",
|
|
|
|
token_string,
|
|
|
|
expected_string,
|
|
|
|
message_prefix,
|
|
|
|
message);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (print_unexp)
|
|
|
|
msg_handler (scanner,
|
|
|
|
"unexpected %s%s%s",
|
|
|
|
token_string,
|
|
|
|
message_prefix,
|
|
|
|
message);
|
|
|
|
else
|
|
|
|
msg_handler (scanner,
|
|
|
|
"%s%s%s",
|
|
|
|
token_string,
|
|
|
|
message_prefix,
|
|
|
|
message);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (token_string);
|
|
|
|
g_free (expected_string);
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
g_scanner_stat_mode (const gchar *filename)
|
|
|
|
{
|
|
|
|
struct stat *stat_buf;
|
1998-07-23 00:32:22 +02:00
|
|
|
gint st_mode;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
stat_buf = g_new0 (struct stat, 1);
|
removed dummy structure definitions for struct _GCache, _GTree, _GTimer,
Tue Oct 27 03:00:50 1998 Tim Janik <timj@gtk.org>
* glib.h: removed dummy structure definitions for struct _GCache,
_GTree, _GTimer, _GMemChunk, _GListAllocator and _GStringChunk.
* gutils.c: implement glib's inline functions _after_ all include
statements have been processed.
removed Tor's MAXPATHLEN check since there already was one supplied
further down in this file.
(LibMain): special cased the #ifdef __LCC__ case for NATIVE_WIN32,
since lcc maybe used on other platforms as well. why in hell is this
stuff required?
(g_get_any_init): for windows, if the user name is supplied, use it as
realname also.
in general, if there is no homedir specified, use the tmpdir that
we already figured.
* gtimer.c (g_timer_elapsed): changed a g_assert() statement to
g_return_if_fail().
* applied glib-tml-981020-0.patch for WIN32 portability, added some
comments and g_return_if_fail() statements, minor indentation fixes.
ChangeLog entry from Tor Lillqvist is appended.
* glib.h (struct dirent): use lower case structure members.
* glib.h:
* makefile.lcc:
* makefile.msc:
s/COMPILING_GLIB/GLIB_COMPILATION/
1998-10-20: Tor Lillqvist <tml@iki.fi>
* README.win32 glib.def gmodule.def
* glibconfig.h.win32 gmodule/gmoduleconf.h.win32:
New files for the Windows port. The .def files list exported
symbols for the Microsoft linker and compatibles.
* configure.in:
Added checks for some platform-dependent headers: pwd.h sys/param.h
sys/select.h sys/time.h sys/times.h unistd.h, and the function lstat.
* gerror.c:
Conditionalized inclusion of system-dependent headers. Changes
for Windows: no gdb to do a stack trace. Just call abort().
* glib.h:
Changes for Windows:
Added macros G_DIR_SEPARATOR, G_DIR_SEPARATOR_S for
platform-dependent file name syntax elements. Added macros
G_SEARCHPATH_SEPARATOR, G_SEARCHPATH_SEPARATOR_S for
platform-dependent search path syntax conventions.
Added pragmas for Microsoft C to make it more pedantic.
Marked GLib's global variables for export from DLL.
Added the function g_strescape that escapes backslashes.
Added functions g_path_is_absolute and g_path_skip_root to
handle platform-dependent file name syntax.
Added the function g_getenv that expands environment variables
that contain references to other environment variables, as is
typical on Windows NT.
Added the GIOChannel structure which is used to encapsulate the
IPC mechanism used by the GIMP's plug-ins, and possibly other
things later. On Unix a GIOChannel encapsulates just a file
descriptor. On Windows it contains a file handle from _pipe() and a
few other things related to the implementation of gdk_input_add
and GIMP plug-in communication. Subject to change.
Removed duplicate declarations of the version variables.
For the Microsoft compiler, declare own implementation of
ftruncate and the <dirent.h> functions.
* gmem.c:
Define a symbolic name for the profiling table size.
* gmessages.c:
Conditionalized inclusion of unistd.h. On Windows, output using
stdio to stdout.
* gscanner.c:
Conditionalized inclusion of unistd.h. Added changes for
Microsoft C. Added CR to the skipped character set. Added small
workaround for MSC compiler bug in g_scanner_cur_value.
* gstrfuncs.c:
Added the function g_strescape, which escapes the backslash
character. Needed especially when printing Windows filenames.
* gtimer.c:
Conditionalized inclusion of unistd.h and sys/time.h. Added
implementations for Windows.
* gutils.c:
Conditionalized inclusion of platform-dependent headers. Use
the platform-independent file name syntax macros.
Conditionalize code on platform-dependent features. Added the
functions g_path_is_absolute g_path_skip_root and g_getenv.
Added the GIOChannel-related functions. Added
compiler-dependent Unix compatibility functions for Windows.
* makefile.lcc makefile.msc:
New files. Compiler-specific makefiles for LCC-Win32 and
Microsoft C. Only Microsoft C is actually supported currently.
* testglib.c:
Added pathname check cases for Windows. Added workaround for
bug in the Microsoft runtime library. Improved some tests a bit.
Tue Oct 27 04:00:11 1998 Tim Janik <timj@gtk.org>
* testgmodule.c (main): changed the #ifdef WIN32 test to NATIVE_WIN32,
this needs to be more constistent throughout the code, do we go for
NATIVE_WIN32 or WIN32?
* gmodule.c (LibMain): special cased the #ifdef __LCC__ case for
NATIVE_WIN32, since lcc maybe used on other platforms as well.
* libgplugin_a.c (LibMain):
* libgplugin_b.c (LibMain):
likewise. not sure i like this special requirement for lcc in here.
* gmodule-dl.c (_g_module_build_path):
feature empty "" directories and prepend the module name with "lib".
* gmodule-dld.c (_g_module_build_path):
* gmodule-win32.c (_g_module_build_path):
feature empty "" directories.
* we need some more magic in the _g_module_build_path variants
so we don't append/prepend lib and .so, .sl or .dll for those names
that already contain it.
* applied patch from Tor Lillqvist for g_module_build_path() and
windows support.
1998-10-20: Tor Lillqvist <tml@iki.fi>
* gmodule/gmodule-win32.c:
New file.
* gmodule/gmodule.c gmodule/gmodule.h:
Added the funcion g_module_build_path that builds the path to
a module file, decorating the name according to the system's
conventions. Added the Windows implementation.
* gmodule/libgplugin_a.c gmodule/libgplugin_b.c:
Added LibMain for LCC-Win32.
* gmodule/testgmodule.c:
Handle Windows dll names.
1998-10-27 05:11:34 +01:00
|
|
|
#ifdef HAVE_LSTAT
|
1998-06-11 01:21:14 +02:00
|
|
|
lstat (filename, stat_buf);
|
removed dummy structure definitions for struct _GCache, _GTree, _GTimer,
Tue Oct 27 03:00:50 1998 Tim Janik <timj@gtk.org>
* glib.h: removed dummy structure definitions for struct _GCache,
_GTree, _GTimer, _GMemChunk, _GListAllocator and _GStringChunk.
* gutils.c: implement glib's inline functions _after_ all include
statements have been processed.
removed Tor's MAXPATHLEN check since there already was one supplied
further down in this file.
(LibMain): special cased the #ifdef __LCC__ case for NATIVE_WIN32,
since lcc maybe used on other platforms as well. why in hell is this
stuff required?
(g_get_any_init): for windows, if the user name is supplied, use it as
realname also.
in general, if there is no homedir specified, use the tmpdir that
we already figured.
* gtimer.c (g_timer_elapsed): changed a g_assert() statement to
g_return_if_fail().
* applied glib-tml-981020-0.patch for WIN32 portability, added some
comments and g_return_if_fail() statements, minor indentation fixes.
ChangeLog entry from Tor Lillqvist is appended.
* glib.h (struct dirent): use lower case structure members.
* glib.h:
* makefile.lcc:
* makefile.msc:
s/COMPILING_GLIB/GLIB_COMPILATION/
1998-10-20: Tor Lillqvist <tml@iki.fi>
* README.win32 glib.def gmodule.def
* glibconfig.h.win32 gmodule/gmoduleconf.h.win32:
New files for the Windows port. The .def files list exported
symbols for the Microsoft linker and compatibles.
* configure.in:
Added checks for some platform-dependent headers: pwd.h sys/param.h
sys/select.h sys/time.h sys/times.h unistd.h, and the function lstat.
* gerror.c:
Conditionalized inclusion of system-dependent headers. Changes
for Windows: no gdb to do a stack trace. Just call abort().
* glib.h:
Changes for Windows:
Added macros G_DIR_SEPARATOR, G_DIR_SEPARATOR_S for
platform-dependent file name syntax elements. Added macros
G_SEARCHPATH_SEPARATOR, G_SEARCHPATH_SEPARATOR_S for
platform-dependent search path syntax conventions.
Added pragmas for Microsoft C to make it more pedantic.
Marked GLib's global variables for export from DLL.
Added the function g_strescape that escapes backslashes.
Added functions g_path_is_absolute and g_path_skip_root to
handle platform-dependent file name syntax.
Added the function g_getenv that expands environment variables
that contain references to other environment variables, as is
typical on Windows NT.
Added the GIOChannel structure which is used to encapsulate the
IPC mechanism used by the GIMP's plug-ins, and possibly other
things later. On Unix a GIOChannel encapsulates just a file
descriptor. On Windows it contains a file handle from _pipe() and a
few other things related to the implementation of gdk_input_add
and GIMP plug-in communication. Subject to change.
Removed duplicate declarations of the version variables.
For the Microsoft compiler, declare own implementation of
ftruncate and the <dirent.h> functions.
* gmem.c:
Define a symbolic name for the profiling table size.
* gmessages.c:
Conditionalized inclusion of unistd.h. On Windows, output using
stdio to stdout.
* gscanner.c:
Conditionalized inclusion of unistd.h. Added changes for
Microsoft C. Added CR to the skipped character set. Added small
workaround for MSC compiler bug in g_scanner_cur_value.
* gstrfuncs.c:
Added the function g_strescape, which escapes the backslash
character. Needed especially when printing Windows filenames.
* gtimer.c:
Conditionalized inclusion of unistd.h and sys/time.h. Added
implementations for Windows.
* gutils.c:
Conditionalized inclusion of platform-dependent headers. Use
the platform-independent file name syntax macros.
Conditionalize code on platform-dependent features. Added the
functions g_path_is_absolute g_path_skip_root and g_getenv.
Added the GIOChannel-related functions. Added
compiler-dependent Unix compatibility functions for Windows.
* makefile.lcc makefile.msc:
New files. Compiler-specific makefiles for LCC-Win32 and
Microsoft C. Only Microsoft C is actually supported currently.
* testglib.c:
Added pathname check cases for Windows. Added workaround for
bug in the Microsoft runtime library. Improved some tests a bit.
Tue Oct 27 04:00:11 1998 Tim Janik <timj@gtk.org>
* testgmodule.c (main): changed the #ifdef WIN32 test to NATIVE_WIN32,
this needs to be more constistent throughout the code, do we go for
NATIVE_WIN32 or WIN32?
* gmodule.c (LibMain): special cased the #ifdef __LCC__ case for
NATIVE_WIN32, since lcc maybe used on other platforms as well.
* libgplugin_a.c (LibMain):
* libgplugin_b.c (LibMain):
likewise. not sure i like this special requirement for lcc in here.
* gmodule-dl.c (_g_module_build_path):
feature empty "" directories and prepend the module name with "lib".
* gmodule-dld.c (_g_module_build_path):
* gmodule-win32.c (_g_module_build_path):
feature empty "" directories.
* we need some more magic in the _g_module_build_path variants
so we don't append/prepend lib and .so, .sl or .dll for those names
that already contain it.
* applied patch from Tor Lillqvist for g_module_build_path() and
windows support.
1998-10-20: Tor Lillqvist <tml@iki.fi>
* gmodule/gmodule-win32.c:
New file.
* gmodule/gmodule.c gmodule/gmodule.h:
Added the funcion g_module_build_path that builds the path to
a module file, decorating the name according to the system's
conventions. Added the Windows implementation.
* gmodule/libgplugin_a.c gmodule/libgplugin_b.c:
Added LibMain for LCC-Win32.
* gmodule/testgmodule.c:
Handle Windows dll names.
1998-10-27 05:11:34 +01:00
|
|
|
#else
|
|
|
|
stat (filename, stat_buf);
|
|
|
|
#endif
|
1998-06-11 01:21:14 +02:00
|
|
|
st_mode = stat_buf->st_mode;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
g_free (stat_buf);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-06-11 01:21:14 +02:00
|
|
|
return st_mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
g_scanner_get_token_i (GScanner *scanner,
|
|
|
|
GTokenType *token_p,
|
1998-09-21 04:32:30 +02:00
|
|
|
GTokenValue *value_p,
|
1998-06-11 01:21:14 +02:00
|
|
|
guint *line_p,
|
|
|
|
guint *position_p)
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
g_scanner_free_value (token_p, value_p);
|
|
|
|
g_scanner_get_token_ll (scanner, token_p, value_p, line_p, position_p);
|
|
|
|
}
|
|
|
|
while (((*token_p > 0 && *token_p < 256) &&
|
|
|
|
strchr (scanner->config->cset_skip_characters, *token_p)) ||
|
|
|
|
(*token_p == G_TOKEN_CHAR &&
|
|
|
|
strchr (scanner->config->cset_skip_characters, value_p->v_char)) ||
|
|
|
|
(*token_p == G_TOKEN_COMMENT_MULTI &&
|
|
|
|
scanner->config->skip_comment_multi) ||
|
|
|
|
(*token_p == G_TOKEN_COMMENT_SINGLE &&
|
|
|
|
scanner->config->skip_comment_single));
|
|
|
|
|
|
|
|
switch (*token_p)
|
|
|
|
{
|
1998-07-23 00:32:22 +02:00
|
|
|
case G_TOKEN_IDENTIFIER:
|
1998-06-11 01:21:14 +02:00
|
|
|
if (scanner->config->identifier_2_string)
|
|
|
|
*token_p = G_TOKEN_STRING;
|
|
|
|
break;
|
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
case G_TOKEN_SYMBOL:
|
1998-06-11 01:21:14 +02:00
|
|
|
if (scanner->config->symbol_2_token)
|
|
|
|
*token_p = (GTokenType) value_p->v_symbol;
|
|
|
|
break;
|
|
|
|
|
1998-07-23 00:32:22 +02:00
|
|
|
case G_TOKEN_BINARY:
|
|
|
|
case G_TOKEN_OCTAL:
|
|
|
|
case G_TOKEN_HEX:
|
1998-06-11 01:21:14 +02:00
|
|
|
if (scanner->config->numbers_2_int)
|
|
|
|
*token_p = G_TOKEN_INT;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*token_p == G_TOKEN_INT &&
|
|
|
|
scanner->config->int_2_float)
|
|
|
|
{
|
|
|
|
*token_p = G_TOKEN_FLOAT;
|
|
|
|
value_p->v_float = value_p->v_int;
|
|
|
|
}
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
g_scanner_get_token_ll (GScanner *scanner,
|
|
|
|
GTokenType *token_p,
|
1998-09-21 04:32:30 +02:00
|
|
|
GTokenValue *value_p,
|
1998-06-11 01:21:14 +02:00
|
|
|
guint *line_p,
|
|
|
|
guint *position_p)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
GScannerConfig *config;
|
|
|
|
GTokenType token;
|
|
|
|
gboolean in_comment_multi;
|
|
|
|
gboolean in_comment_single;
|
|
|
|
gboolean in_string_sq;
|
|
|
|
gboolean in_string_dq;
|
|
|
|
GString *gstring;
|
|
|
|
GTokenValue value;
|
|
|
|
guchar ch;
|
1998-06-11 01:21:14 +02:00
|
|
|
|
|
|
|
config = scanner->config;
|
|
|
|
(*value_p).v_int = 0;
|
|
|
|
|
1998-09-25 02:44:38 +02:00
|
|
|
if ((scanner->text >= scanner->text_end && scanner->input_fd < 0) ||
|
|
|
|
scanner->token == G_TOKEN_EOF)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
|
|
|
*token_p = G_TOKEN_EOF;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
in_comment_multi = FALSE;
|
|
|
|
in_comment_single = FALSE;
|
|
|
|
in_string_sq = FALSE;
|
|
|
|
in_string_dq = FALSE;
|
|
|
|
gstring = NULL;
|
|
|
|
|
1998-09-25 02:44:38 +02:00
|
|
|
do /* while (ch != 0) */
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
gboolean dotted_float = FALSE;
|
1998-06-11 01:21:14 +02:00
|
|
|
|
|
|
|
ch = g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
|
|
|
|
value.v_int = 0;
|
|
|
|
token = G_TOKEN_NONE;
|
|
|
|
|
|
|
|
/* this is *evil*, but needed ;(
|
|
|
|
* we first check for identifier first character, because it
|
|
|
|
* might interfere with other key chars like slashes or numbers
|
|
|
|
*/
|
|
|
|
if (config->scan_identifier &&
|
|
|
|
ch && strchr (config->cset_identifier_first, ch))
|
|
|
|
goto identifier_precedence;
|
|
|
|
|
|
|
|
switch (ch)
|
|
|
|
{
|
1999-01-02 02:32:37 +01:00
|
|
|
case 0:
|
1998-06-11 01:21:14 +02:00
|
|
|
token = G_TOKEN_EOF;
|
|
|
|
(*position_p)++;
|
1998-09-25 02:44:38 +02:00
|
|
|
/* ch = 0; */
|
1998-06-11 01:21:14 +02:00
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case '/':
|
1998-06-11 01:21:14 +02:00
|
|
|
if (!config->scan_comment_multi ||
|
|
|
|
g_scanner_peek_next_char (scanner) != '*')
|
|
|
|
goto default_case;
|
|
|
|
g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
token = G_TOKEN_COMMENT_MULTI;
|
|
|
|
in_comment_multi = TRUE;
|
|
|
|
gstring = g_string_new ("");
|
|
|
|
while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
|
|
|
|
{
|
|
|
|
if (ch == '*' && g_scanner_peek_next_char (scanner) == '/')
|
|
|
|
{
|
|
|
|
g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
in_comment_multi = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gstring = g_string_append_c (gstring, ch);
|
|
|
|
}
|
|
|
|
ch = 0;
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case '\'':
|
1998-06-11 01:21:14 +02:00
|
|
|
if (!config->scan_string_sq)
|
|
|
|
goto default_case;
|
|
|
|
token = G_TOKEN_STRING;
|
|
|
|
in_string_sq = TRUE;
|
|
|
|
gstring = g_string_new ("");
|
|
|
|
while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
|
|
|
|
{
|
|
|
|
if (ch == '\'')
|
|
|
|
{
|
|
|
|
in_string_sq = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gstring = g_string_append_c (gstring, ch);
|
|
|
|
}
|
|
|
|
ch = 0;
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case '"':
|
1998-06-11 01:21:14 +02:00
|
|
|
if (!config->scan_string_dq)
|
|
|
|
goto default_case;
|
|
|
|
token = G_TOKEN_STRING;
|
|
|
|
in_string_dq = TRUE;
|
|
|
|
gstring = g_string_new ("");
|
|
|
|
while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
|
|
|
|
{
|
|
|
|
if (ch == '"')
|
|
|
|
{
|
|
|
|
in_string_dq = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (ch == '\\')
|
|
|
|
{
|
|
|
|
ch = g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
switch (ch)
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
guint i;
|
|
|
|
guint fchar;
|
1998-06-11 01:21:14 +02:00
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case 0:
|
1998-06-11 01:21:14 +02:00
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case '\\':
|
1998-06-11 01:21:14 +02:00
|
|
|
gstring = g_string_append_c (gstring, '\\');
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case 'n':
|
1998-06-11 01:21:14 +02:00
|
|
|
gstring = g_string_append_c (gstring, '\n');
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case 't':
|
1998-06-11 01:21:14 +02:00
|
|
|
gstring = g_string_append_c (gstring, '\t');
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case 'r':
|
1998-06-11 01:21:14 +02:00
|
|
|
gstring = g_string_append_c (gstring, '\r');
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case 'b':
|
1998-06-11 01:21:14 +02:00
|
|
|
gstring = g_string_append_c (gstring, '\b');
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case 'f':
|
1998-06-11 01:21:14 +02:00
|
|
|
gstring = g_string_append_c (gstring, '\f');
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case '0':
|
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
case '3':
|
|
|
|
case '4':
|
|
|
|
case '5':
|
|
|
|
case '6':
|
|
|
|
case '7':
|
1998-06-11 01:21:14 +02:00
|
|
|
i = ch - '0';
|
|
|
|
fchar = g_scanner_peek_next_char (scanner);
|
|
|
|
if (fchar >= '0' && fchar <= '7')
|
|
|
|
{
|
|
|
|
ch = g_scanner_get_char (scanner, line_p, position_p);
|
1998-09-25 02:44:38 +02:00
|
|
|
i = i * 8 + ch - '0';
|
1998-06-11 01:21:14 +02:00
|
|
|
fchar = g_scanner_peek_next_char (scanner);
|
|
|
|
if (fchar >= '0' && fchar <= '7')
|
|
|
|
{
|
|
|
|
ch = g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
i = i * 8 + ch - '0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gstring = g_string_append_c (gstring, i);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
gstring = g_string_append_c (gstring, ch);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gstring = g_string_append_c (gstring, ch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ch = 0;
|
|
|
|
break;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case '.':
|
1998-06-11 01:21:14 +02:00
|
|
|
if (!config->scan_float)
|
|
|
|
goto default_case;
|
|
|
|
token = G_TOKEN_FLOAT;
|
|
|
|
dotted_float = TRUE;
|
|
|
|
ch = g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
goto number_parsing;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case '$':
|
1998-06-11 01:21:14 +02:00
|
|
|
if (!config->scan_hex_dollar)
|
|
|
|
goto default_case;
|
|
|
|
token = G_TOKEN_HEX;
|
|
|
|
ch = g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
goto number_parsing;
|
|
|
|
|
1999-01-02 02:32:37 +01:00
|
|
|
case '0':
|
1998-06-11 01:21:14 +02:00
|
|
|
if (config->scan_octal)
|
|
|
|
token = G_TOKEN_OCTAL;
|
|
|
|
else
|
|
|
|
token = G_TOKEN_INT;
|
|
|
|
ch = g_scanner_peek_next_char (scanner);
|
|
|
|
if (config->scan_hex && (ch == 'x' || ch == 'X'))
|
|
|
|
{
|
|
|
|
token = G_TOKEN_HEX;
|
|
|
|
g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
ch = g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
if (ch == 0)
|
|
|
|
{
|
|
|
|
token = G_TOKEN_ERROR;
|
|
|
|
value.v_error = G_ERR_UNEXP_EOF;
|
|
|
|
(*position_p)++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (g_scanner_char_2_num (ch, 16) < 0)
|
|
|
|
{
|
|
|
|
token = G_TOKEN_ERROR;
|
|
|
|
value.v_error = G_ERR_DIGIT_RADIX;
|
|
|
|
ch = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (config->scan_binary && (ch == 'b' || ch == 'B'))
|
|
|
|
{
|
|
|
|
token = G_TOKEN_BINARY;
|
|
|
|
g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
ch = g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
if (ch == 0)
|
|
|
|
{
|
|
|
|
token = G_TOKEN_ERROR;
|
|
|
|
value.v_error = G_ERR_UNEXP_EOF;
|
|
|
|
(*position_p)++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (g_scanner_char_2_num (ch, 10) < 0)
|
|
|
|
{
|
|
|
|
token = G_TOKEN_ERROR;
|
|
|
|
value.v_error = G_ERR_NON_DIGIT_IN_CONST;
|
|
|
|
ch = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ch = '0';
|
|
|
|
/* fall through */
|
1999-01-02 02:32:37 +01:00
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
case '3':
|
|
|
|
case '4':
|
|
|
|
case '5':
|
|
|
|
case '6':
|
|
|
|
case '7':
|
|
|
|
case '8':
|
|
|
|
case '9':
|
1998-06-11 01:21:14 +02:00
|
|
|
number_parsing:
|
1998-09-25 02:44:38 +02:00
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
gboolean in_number = TRUE;
|
1998-09-25 02:44:38 +02:00
|
|
|
gchar *endptr;
|
|
|
|
|
|
|
|
if (token == G_TOKEN_NONE)
|
|
|
|
token = G_TOKEN_INT;
|
|
|
|
|
|
|
|
gstring = g_string_new (dotted_float ? "0." : "");
|
|
|
|
gstring = g_string_append_c (gstring, ch);
|
|
|
|
|
|
|
|
do /* while (in_number) */
|
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
gboolean is_E;
|
1998-09-25 02:44:38 +02:00
|
|
|
|
|
|
|
is_E = token == G_TOKEN_FLOAT && (ch == 'e' || ch == 'E');
|
|
|
|
|
|
|
|
ch = g_scanner_peek_next_char (scanner);
|
|
|
|
|
|
|
|
if (g_scanner_char_2_num (ch, 36) >= 0 ||
|
|
|
|
(config->scan_float && ch == '.') ||
|
|
|
|
(is_E && (ch == '+' || ch == '-')))
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-09-25 02:44:38 +02:00
|
|
|
ch = g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
|
|
|
|
switch (ch)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-09-25 02:44:38 +02:00
|
|
|
case '.':
|
|
|
|
if (token != G_TOKEN_INT && token != G_TOKEN_OCTAL)
|
|
|
|
{
|
|
|
|
value.v_error = token == G_TOKEN_FLOAT ? G_ERR_FLOAT_MALFORMED : G_ERR_FLOAT_RADIX;
|
|
|
|
token = G_TOKEN_ERROR;
|
|
|
|
in_number = FALSE;
|
|
|
|
}
|
1998-06-11 01:21:14 +02:00
|
|
|
else
|
1998-09-25 02:44:38 +02:00
|
|
|
{
|
|
|
|
token = G_TOKEN_FLOAT;
|
|
|
|
gstring = g_string_append_c (gstring, ch);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '0':
|
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
case '3':
|
|
|
|
case '4':
|
|
|
|
case '5':
|
|
|
|
case '6':
|
|
|
|
case '7':
|
|
|
|
case '8':
|
|
|
|
case '9':
|
1998-06-11 01:21:14 +02:00
|
|
|
gstring = g_string_append_c (gstring, ch);
|
1998-09-25 02:44:38 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case '-':
|
|
|
|
case '+':
|
|
|
|
if (token != G_TOKEN_FLOAT)
|
|
|
|
{
|
|
|
|
token = G_TOKEN_ERROR;
|
|
|
|
value.v_error = G_ERR_NON_DIGIT_IN_CONST;
|
|
|
|
in_number = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gstring = g_string_append_c (gstring, ch);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'e':
|
|
|
|
case 'E':
|
|
|
|
if ((token != G_TOKEN_HEX && !config->scan_float) ||
|
|
|
|
(token != G_TOKEN_HEX &&
|
|
|
|
token != G_TOKEN_OCTAL &&
|
|
|
|
token != G_TOKEN_FLOAT &&
|
|
|
|
token != G_TOKEN_INT))
|
|
|
|
{
|
|
|
|
token = G_TOKEN_ERROR;
|
|
|
|
value.v_error = G_ERR_NON_DIGIT_IN_CONST;
|
|
|
|
in_number = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (token != G_TOKEN_HEX)
|
|
|
|
token = G_TOKEN_FLOAT;
|
|
|
|
gstring = g_string_append_c (gstring, ch);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if (token != G_TOKEN_HEX)
|
|
|
|
{
|
|
|
|
token = G_TOKEN_ERROR;
|
|
|
|
value.v_error = G_ERR_NON_DIGIT_IN_CONST;
|
|
|
|
in_number = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gstring = g_string_append_c (gstring, ch);
|
|
|
|
break;
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
1998-09-25 02:44:38 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
in_number = FALSE;
|
|
|
|
}
|
|
|
|
while (in_number);
|
|
|
|
|
|
|
|
endptr = NULL;
|
|
|
|
switch (token)
|
|
|
|
{
|
|
|
|
case G_TOKEN_BINARY:
|
|
|
|
value.v_binary = strtol (gstring->str, &endptr, 2);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TOKEN_OCTAL:
|
|
|
|
value.v_octal = strtol (gstring->str, &endptr, 8);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TOKEN_INT:
|
|
|
|
value.v_int = strtol (gstring->str, &endptr, 10);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TOKEN_FLOAT:
|
|
|
|
value.v_float = g_strtod (gstring->str, &endptr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TOKEN_HEX:
|
|
|
|
value.v_hex = strtol (gstring->str, &endptr, 16);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (endptr && *endptr)
|
|
|
|
{
|
|
|
|
token = G_TOKEN_ERROR;
|
|
|
|
if (*endptr == 'e' || *endptr == 'E')
|
|
|
|
value.v_error = G_ERR_NON_DIGIT_IN_CONST;
|
|
|
|
else
|
|
|
|
value.v_error = G_ERR_DIGIT_RADIX;
|
|
|
|
}
|
|
|
|
g_string_free (gstring, TRUE);
|
|
|
|
gstring = NULL;
|
|
|
|
ch = 0;
|
|
|
|
} /* number_parsing:... */
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
default_case:
|
|
|
|
{
|
|
|
|
if (config->cpair_comment_single &&
|
|
|
|
ch == config->cpair_comment_single[0])
|
|
|
|
{
|
|
|
|
token = G_TOKEN_COMMENT_SINGLE;
|
|
|
|
in_comment_single = TRUE;
|
|
|
|
gstring = g_string_new ("");
|
2000-05-19 10:18:29 +02:00
|
|
|
ch = g_scanner_get_char (scanner, line_p, position_p);
|
|
|
|
while (ch != 0)
|
1998-09-25 02:44:38 +02:00
|
|
|
{
|
|
|
|
if (ch == config->cpair_comment_single[1])
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-09-25 02:44:38 +02:00
|
|
|
in_comment_single = FALSE;
|
|
|
|
ch = 0;
|
|
|
|
break;
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
|
1998-09-25 02:44:38 +02:00
|
|
|
gstring = g_string_append_c (gstring, ch);
|
2000-05-19 10:18:29 +02:00
|
|
|
ch = g_scanner_get_char (scanner, line_p, position_p);
|
1998-09-25 02:44:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (config->scan_identifier && ch &&
|
|
|
|
strchr (config->cset_identifier_first, ch))
|
|
|
|
{
|
|
|
|
identifier_precedence:
|
|
|
|
|
|
|
|
if (config->cset_identifier_nth && ch &&
|
|
|
|
strchr (config->cset_identifier_nth,
|
|
|
|
g_scanner_peek_next_char (scanner)))
|
|
|
|
{
|
|
|
|
token = G_TOKEN_IDENTIFIER;
|
|
|
|
gstring = g_string_new ("");
|
|
|
|
gstring = g_string_append_c (gstring, ch);
|
|
|
|
do
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-09-25 02:44:38 +02:00
|
|
|
ch = g_scanner_get_char (scanner, line_p, position_p);
|
1998-06-11 01:21:14 +02:00
|
|
|
gstring = g_string_append_c (gstring, ch);
|
1998-09-25 02:44:38 +02:00
|
|
|
ch = g_scanner_peek_next_char (scanner);
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
1998-09-25 02:44:38 +02:00
|
|
|
while (ch && strchr (config->cset_identifier_nth, ch));
|
|
|
|
ch = 0;
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
1998-09-25 02:44:38 +02:00
|
|
|
else if (config->scan_identifier_1char)
|
|
|
|
{
|
|
|
|
token = G_TOKEN_IDENTIFIER;
|
|
|
|
value.v_identifier = g_new0 (gchar, 2);
|
|
|
|
value.v_identifier[0] = ch;
|
|
|
|
ch = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ch)
|
|
|
|
{
|
|
|
|
if (config->char_2_token)
|
|
|
|
token = ch;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
token = G_TOKEN_CHAR;
|
|
|
|
value.v_char = ch;
|
|
|
|
}
|
|
|
|
ch = 0;
|
|
|
|
}
|
|
|
|
} /* default_case:... */
|
1998-06-11 01:21:14 +02:00
|
|
|
break;
|
|
|
|
}
|
1998-09-25 02:44:38 +02:00
|
|
|
g_assert (ch == 0 && token != G_TOKEN_NONE); /* paranoid */
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
while (ch != 0);
|
|
|
|
|
1998-09-25 02:44:38 +02:00
|
|
|
if (in_comment_multi || in_comment_single ||
|
|
|
|
in_string_sq || in_string_dq)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
|
|
|
token = G_TOKEN_ERROR;
|
|
|
|
if (gstring)
|
|
|
|
{
|
|
|
|
g_string_free (gstring, TRUE);
|
|
|
|
gstring = NULL;
|
|
|
|
}
|
|
|
|
(*position_p)++;
|
|
|
|
if (in_comment_multi || in_comment_single)
|
|
|
|
value.v_error = G_ERR_UNEXP_EOF_IN_COMMENT;
|
1998-09-25 02:44:38 +02:00
|
|
|
else /* (in_string_sq || in_string_dq) */
|
1998-06-11 01:21:14 +02:00
|
|
|
value.v_error = G_ERR_UNEXP_EOF_IN_STRING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gstring)
|
|
|
|
{
|
|
|
|
value.v_string = gstring->str;
|
|
|
|
g_string_free (gstring, FALSE);
|
|
|
|
gstring = NULL;
|
|
|
|
}
|
|
|
|
|
1998-09-25 02:44:38 +02:00
|
|
|
if (token == G_TOKEN_IDENTIFIER)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-09-25 02:44:38 +02:00
|
|
|
if (config->scan_symbols)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1999-01-04 21:09:59 +01:00
|
|
|
GScannerKey *key;
|
|
|
|
guint scope_id;
|
1998-09-25 02:44:38 +02:00
|
|
|
|
|
|
|
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 (key)
|
|
|
|
{
|
|
|
|
g_free (value.v_identifier);
|
|
|
|
token = G_TOKEN_SYMBOL;
|
|
|
|
value.v_symbol = key->value;
|
|
|
|
}
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
|
1998-09-25 02:44:38 +02:00
|
|
|
if (token == G_TOKEN_IDENTIFIER &&
|
|
|
|
config->scan_identifier_NULL &&
|
|
|
|
strlen (value.v_identifier) == 4)
|
1998-06-11 01:21:14 +02:00
|
|
|
{
|
1998-09-25 02:44:38 +02:00
|
|
|
gchar *null_upper = "NULL";
|
|
|
|
gchar *null_lower = "null";
|
|
|
|
|
|
|
|
if (scanner->config->case_sensitive)
|
|
|
|
{
|
|
|
|
if (value.v_identifier[0] == null_upper[0] &&
|
|
|
|
value.v_identifier[1] == null_upper[1] &&
|
|
|
|
value.v_identifier[2] == null_upper[2] &&
|
|
|
|
value.v_identifier[3] == null_upper[3])
|
|
|
|
token = G_TOKEN_IDENTIFIER_NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((value.v_identifier[0] == null_upper[0] ||
|
|
|
|
value.v_identifier[0] == null_lower[0]) &&
|
|
|
|
(value.v_identifier[1] == null_upper[1] ||
|
|
|
|
value.v_identifier[1] == null_lower[1]) &&
|
|
|
|
(value.v_identifier[2] == null_upper[2] ||
|
|
|
|
value.v_identifier[2] == null_lower[2]) &&
|
|
|
|
(value.v_identifier[3] == null_upper[3] ||
|
|
|
|
value.v_identifier[3] == null_lower[3]))
|
|
|
|
token = G_TOKEN_IDENTIFIER_NULL;
|
|
|
|
}
|
1998-06-11 01:21:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*token_p = token;
|
|
|
|
*value_p = value;
|
|
|
|
}
|