From 3a6373d888021388473bd96c000a8fdab8aedaa5 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Mon, 20 Apr 2009 15:05:56 +0300 Subject: Switch to the Grecs submodule. * gconf: Remove * Makefile.am (ACLOCAL_AMFLAGS): Add -I grecs/am. (SUBDIRS): Replace gconf with grecs (make-ChangeLog): Remove spurious rule. * bootstrap.conf: Init submodules. * configure.ac: Call GRECS_SETUP (AC_CONFIG_FILES): Add grecs/Makefile, grecs/src/Makefile. * src/wydawca.h: Include grecs.h * src/Makefile.am (LDADD,INCLUDES): Refer to grecs. * tests/Makefile.am: Likewise. * src/cmdline.opt, src/config.c, src/diskio.c, src/tcpwrap.c, src/wydawca.c: Use grecs. * README-hacking: Update --- .gitignore | 4 +- .gitmodules | 3 + Makefile.am | 22 +- README-hacking | 35 +- bootstrap.conf | 7 +- configure.ac | 46 +-- gconf/.gitignore | 4 - gconf/Makefile.am | 17 - gconf/gconf-format.c | 200 ----------- gconf/gconf-gram.y | 891 -------------------------------------------------- gconf/gconf-lex.l | 476 --------------------------- gconf/gconf-preproc.c | 728 ----------------------------------------- gconf/gconf-text.c | 73 ----- gconf/gconf.h | 163 --------- gconf/gnulib.modules | 14 - gconf/wordsplit.c | 568 -------------------------------- gconf/wordsplit.h | 88 ----- grecs | 1 + src/Makefile.am | 4 +- src/cmdline.opt | 18 +- src/config.c | 476 +++++++++++++-------------- src/diskio.c | 8 +- src/tcpwrap.c | 22 +- src/wydawca.c | 10 +- src/wydawca.h | 14 +- tests/Makefile.am | 4 +- 26 files changed, 321 insertions(+), 3575 deletions(-) create mode 100644 .gitmodules delete mode 100644 gconf/.gitignore delete mode 100644 gconf/Makefile.am delete mode 100644 gconf/gconf-format.c delete mode 100644 gconf/gconf-gram.y delete mode 100644 gconf/gconf-lex.l delete mode 100644 gconf/gconf-preproc.c delete mode 100644 gconf/gconf-text.c delete mode 100644 gconf/gconf.h delete mode 100644 gconf/gnulib.modules delete mode 100644 gconf/wordsplit.c delete mode 100644 gconf/wordsplit.h create mode 160000 grecs diff --git a/.gitignore b/.gitignore index 5e9c566..4c9b75d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ +*.a +*.o *.tar.* *~ -*.o -*.a .bootstrap .deps .emacs.desktop diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..fea8f96 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "grecs"] + path = grecs + url = git://git.gnu.org.ua/grecs.git diff --git a/Makefile.am b/Makefile.am index 1eac948..743b2be 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,34 +14,16 @@ # You should have received a copy of the GNU General Public License # along with wydawca. If not, see . -ACLOCAL_AMFLAGS = -I m4 +ACLOCAL_AMFLAGS = -I m4 -I grecs/am AUTOMAKE_OPTIONS = gnu 1.8.5 -SUBDIRS=gnu gconf src doc etc tests +SUBDIRS=gnu grecs src doc etc tests # We never remove files from the configuration directory distuninstallcheck_listfiles = \ find $(prefix) -type f -not -path '$(sysconfdir)/*' gen_start_date = 2009-01-25 -.PHONY: make-ChangeLog -make-ChangeLog: - if test -d .git; then \ - $(top_srcdir)/build-aux/gitlog-to-changelog \ - --since=$(gen_start_date) | \ - sed '/$$/d' | fmt -s > $(distdir)/cl-t; \ - cat ChangeLog.svn | sed '/^Local Variables:/,/^End:/d' \ - >> $(distdir)/cl-t; \ - echo "Local Variables:" >> $(distdir)/cl-t; \ - echo "mode: change-log" >> $(distdir)/cl-t; \ - echo "version-control: never" >> $(distdir)/cl-t; \ - echo "buffer-read-only: t" >> $(distdir)/cl-t; \ - echo "End:" >> $(distdir)/cl-t; \ - rm -f $(distdir)/ChangeLog; \ - mv $(distdir)/cl-t $(distdir)/ChangeLog; \ - fi - -dist-hook: make-ChangeLog .PHONY: ChangeLog ChangeLog: diff --git a/README-hacking b/README-hacking index 19b957a..a746607 100644 --- a/README-hacking +++ b/README-hacking @@ -1,44 +1,59 @@ -These notes intend to help people working on the SVN version of +These notes intend to help people working on the Git version of this package. See end of this file for the copying conditions. * Requirements -You need the following packages to build the SVN version of Wydawca. I do +You need the following packages to build the Git version of Wydawca. I do not make any efforts to accommodate older versions of these packages, so please make sure that you have the latest stable version. - Automake - Autoconf - Bison +- Git - Gnulib +- Grecs - Flex - M4 - Mailutils -- Subversion - Texinfo * Bootstrapping -Obviously, if you are reading these notes, you did manage to check out -the source tree from SVN. The next step is to create the configuration -framework: +Obviously, if you are reading these notes, you did manage to clone +the source tree from the Git repository. The next step is to create +the configuration framework: 1. Change to the source tree directory $ cd wydawca -2. Run `bootstrap' pointing the --gnulib-srcdir option to the location -of the local directory where gnulib sources reside, e.g.: +2. Run `bootstrap': - ./bootstrap --gnulib-srcdir=/usr/src/gnulib + ./bootstrap Once done, proceed as described in the file README (section `Installation'). +Normally you will have to run bootstrap only once. However, if you +intend to hack on Wydawca, you might need to run it again later. In +this case, you will probably want to save some time and bandwidth by +avoiding downloading the same files again. If so, create in the Wydawca +root directory the file named `.bootstrap' with the following +contents: + + --gnulib-srcdir=$HOME/gnulib + +Replace `$HOME/gnulib' with the actual directory where the Gnulib +sources reside. + +For more information about `bootstrap', run `bootstrap --help'. + + * Copyright information - Copyright (C) 2007 Sergey Poznyakoff + Copyright (C) 2007, 2009 Sergey Poznyakoff Permission is granted to anyone to make or distribute verbatim copies of this document as received, in any medium, provided that the diff --git a/bootstrap.conf b/bootstrap.conf index 6119189..fde2671 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -21,6 +21,11 @@ gnulib_mk=Makefile.am test -d $source_base || mkdir -p $source_base +if git config submodule.grecs.url >/dev/null; then : ; else + git submodule init || exit $? + git submodule update || exit $? +fi + # We don't need these modules, even though gnulib-tool mistakenly # includes them because of gettext dependencies. avoided_gnulib_modules=' @@ -29,7 +34,7 @@ avoided_gnulib_modules=' ' # gnulib modules used by this package. -gnulib_modules="`grep -h '^[^#]' gnulib.modules gconf/gnulib.modules | sort | uniq`" +gnulib_modules="`grep -h '^[^#]' gnulib.modules grecs/gnulib.modules | sort | uniq`" # Additional xgettext options to use. Use "\\\newline" to break lines. XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\ diff --git a/configure.ac b/configure.ac index 604ccc4..48e1252 100644 --- a/configure.ac +++ b/configure.ac @@ -106,48 +106,9 @@ fi if test "$status_tcpwrap" = yes; then AC_DEFINE_UNQUOTED([WITH_LIBWRAP],1,[Defined if compiling with libwrap]) fi - -# ********************** -# Preprocessor -# ********************** -AC_ARG_WITH([preprocessor], - AC_HELP_STRING([--without-preprocessor], - [do not use external preprocessor]), - [ -case "${withval}" in -yes) use_ext_pp=yes ;; -no) use_ext_pp=no ;; -*) AC_MSG_ERROR(bad value ${withval} for --with-preprocessor) ;; -esac],[use_ext_pp=yes]) - -if test $use_ext_pp != no; then - # Check for default preprocessor - AC_ARG_VAR([DEFAULT_PREPROCESSOR], - [Set default preprocessor name]) - if test -z "$DEFAULT_PREPROCESSOR" ; then - DEFAULT_PREPROCESSOR="m4 -s" - fi - - save_PATH=$PATH - PREPROC_OPTIONS=`echo $DEFAULT_PREPROCESSOR | sed -n 's/[[^ ]][[^ ]]* //p'` - case "$DEFAULT_PREPROCESSOR" in - /*) PATH=`expr $DEFAULT_PREPROCESSOR : '\(.*\)/.*'`:$PATH - DEFAULT_PREPROCESSOR=`expr $DEFAULT_PREPROCESSOR : '.*/\(.*\)'`;; - esac - AC_PATH_PROG(PPBIN, $DEFAULT_PREPROCESSOR) - DEFAULT_PREPROCESSOR=$PPBIN - if test -n "$DEFAULT_PREPROCESSOR"; then - DEFAULT_PREPROCESSOR="$DEFAULT_PREPROCESSOR $PREPROC_OPTIONS" - case $PPBIN in - *m4) AC_SUBST(PP_SETUP_FILE,'pp-setup');; # Install default pp-setup - esac - fi - PATH=$save_PATH - DEFAULT_PREPROCESSOR="\\\"$DEFAULT_PREPROCESSOR\\\"" -else - DEFAULT_PREPROCESSOR=NULL -fi +# Grecs subsystem +GRECS_SETUP AH_BOTTOM([ #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) @@ -172,7 +133,8 @@ fi AC_CONFIG_FILES([Makefile doc/Makefile gnu/Makefile - gconf/Makefile + grecs/Makefile + grecs/src/Makefile src/Makefile etc/Makefile]) diff --git a/gconf/.gitignore b/gconf/.gitignore deleted file mode 100644 index 42c88b2..0000000 --- a/gconf/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -gconf-gram.c -gconf-gram.h -gconf-gram.output -gconf-lex.c diff --git a/gconf/Makefile.am b/gconf/Makefile.am deleted file mode 100644 index afe06b0..0000000 --- a/gconf/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -noinst_LIBRARIES=libgconf.a -libgconf_a_SOURCES = \ - gconf-format.c\ - gconf-gram.y\ - gconf-lex.l\ - gconf-preproc.c\ - gconf-text.c\ - gconf.h\ - wordsplit.c\ - wordsplit.h - -EXTRA_DIST=gconf-gram.h - -INCLUDES = -I$(top_srcdir)/gnu -I../gnu -AM_YFLAGS = -dtv -AM_LFLAGS = -dvp - diff --git a/gconf/gconf-format.c b/gconf/gconf-format.c deleted file mode 100644 index ea8a808..0000000 --- a/gconf/gconf-format.c +++ /dev/null @@ -1,200 +0,0 @@ -/* gconf - General purpose configuration parser. - Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3 of the License, or (at your - option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program. If not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include -#include -#include -#include -#include - -#if ENABLE_NLS -# include "gettext.h" -#else -# define gettext(s) s -#endif - -#define _(s) gettext (s) -#define N_(s) s - -const char * -gconf_data_type_string (enum gconf_data_type type) -{ - switch (type) - { - case gconf_type_void: - return "void"; - - case gconf_type_string: - return "string"; - - case gconf_type_short: - case gconf_type_ushort: - case gconf_type_int: - case gconf_type_uint: - case gconf_type_long: - case gconf_type_ulong: - case gconf_type_size: -/* case gconf_type_off:*/ - case gconf_type_uintmax: - case gconf_type_intmax: - return "number"; - - case gconf_type_time: - return "time"; - - case gconf_type_bool: - return "boolean"; - - case gconf_type_ipv4: - return "IPv4"; - - case gconf_type_cidr: - return "CIDR"; - - case gconf_type_host: - return "hostname"; - - case gconf_type_sockaddr: - return "sock-addr"; - - case gconf_type_section: - return "section"; - } - return "UNKNOWN?"; -} - -static void -format_level (FILE *stream, unsigned level) -{ - while (level--) - fprintf (stream, " "); -} - -void -gconf_format_docstring (FILE *stream, const char *docstring, unsigned level) -{ - size_t len = strlen (docstring); - int width = 78 - level * 2; - - if (width < 0) - { - width = 78; - level = 0; - } - - while (len) - { - size_t seglen; - const char *p; - - for (seglen = 0, p = docstring; p < docstring + width && *p; p++) - { - if (*p == '\n') - { - seglen = p - docstring; - break; - } - if (isspace (*p)) - seglen = p - docstring; - } - if (seglen == 0 || *p == 0) - seglen = p - docstring; - - format_level (stream, level); - fprintf (stream, "# "); - fwrite (docstring, seglen, 1, stream); - fputc ('\n', stream); - len -= seglen; - docstring += seglen; - if (*docstring == '\n') - { - docstring++; - len--; - } - else - while (*docstring && isspace (*docstring)) - { - docstring++; - len--; - } - } -} - -void -gconf_format_simple_statement (FILE *stream, struct gconf_keyword *kwp, - unsigned level) -{ - const char *argstr; - - if (kwp->docstring) - gconf_format_docstring (stream, kwp->docstring, level); - format_level (stream, level); - - if (kwp->argname) - argstr = kwp->argname; - else - argstr = N_("arg"); - - if (strchr ("<[", argstr[0])) - fprintf (stream, "%s %s;\n", kwp->ident, gettext (argstr)); - else if (strchr (argstr, ':')) - fprintf (stream, "%s <%s>;\n", kwp->ident, gettext (argstr)); - else - { - fprintf (stream, "%s <%s: ", kwp->ident, gettext (argstr)); - if (GCONF_IS_LIST (kwp->type)) - fprintf (stream, "list of %s", - gettext (gconf_data_type_string (GCONF_TYPE (kwp->type)))); - else - fprintf (stream, "%s", gettext (gconf_data_type_string (kwp->type))); - fprintf (stream, ">;\n"); - } -} - -void -gconf_format_block_statement (FILE *stream, struct gconf_keyword *kwp, - unsigned level) -{ - if (kwp->docstring) - gconf_format_docstring (stream, kwp->docstring, level); - format_level (stream, level); - fprintf (stream, "%s", kwp->ident); - if (kwp->argname) - fprintf (stream, " <%s>", gettext (kwp->argname)); - fprintf (stream, " {\n"); - gconf_format_statement_array (stream, kwp->kwd, 0, level + 1); - format_level (stream, level); - fprintf (stream, "}\n"); -} - -void -gconf_format_statement_array (FILE *stream, struct gconf_keyword *kwp, - unsigned n, - unsigned level) -{ - for (; kwp->ident; kwp++, n++) - { - if (n) - fputc ('\n', stream); - if (kwp->type == gconf_type_section) - gconf_format_block_statement (stream, kwp, level); - else - gconf_format_simple_statement (stream, kwp, level); - } -} diff --git a/gconf/gconf-gram.y b/gconf/gconf-gram.y deleted file mode 100644 index c2d833b..0000000 --- a/gconf/gconf-gram.y +++ /dev/null @@ -1,891 +0,0 @@ -%{ -/* gconf - General purpose configuration parser. - Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3 of the License, or (at your - option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program. If not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#if ENABLE_NLS -# include "gettext.h" -# define _(msgid) gettext (msgid) -#else -# define _(msgid) msgid -#endif - -typedef union -{ - struct sockaddr s; - struct sockaddr_in s_in; - struct sockaddr_un s_un; -} sockaddr_union_t; - -static struct gconf_keyword config_keywords; -static struct gconf_keyword *cursect; -static gl_list_t sections; -int gconf_error_count; - -int gconf_default_port = 0; - -static void *target_ptr(struct gconf_keyword *kwp); -static void stmt_begin(struct gconf_keyword *kwp, gconf_value_t tag); -static void stmt_end(struct gconf_keyword *kwp); -static struct gconf_keyword *find_keyword(const char *ident); - -static void process_ident(struct gconf_keyword *kwp, gconf_value_t *value); -static gl_list_t simple_list_create (bool dispose); -%} - -%union { - char *string; - gconf_value_t value; - gl_list_t list; - struct gconf_keyword *kw; -} - -%token IDENT STRING QSTRING MSTRING -%type string slist -%type slist0 -%type value tag vallist -%type values list vlist -%type ident - -%% - -input : stmtlist - ; - -stmtlist: stmt - | stmtlist stmt - ; - -stmt : simple - | block - ; - -simple : ident vallist ';' - { - process_ident($1, &$2); - } - ; - -block : ident tag { stmt_begin($1, $2); } '{' stmtlist '}' opt_sc - { - stmt_end($1); - } - ; - -ident : IDENT - { - $$ = find_keyword($1); - if (!$$) - gconf_error(&gconf_current_locus, 0, _("Unknown keyword")); - } - ; - -tag : /* empty */ - { - $$.type = GCONF_TYPE_STRING; - $$.v.string = NULL; - } - | value - ; - -vallist : vlist - { - size_t n; - - if ((n = gl_list_size ($1)) == 1) - { - $$ = *(gconf_value_t *)gl_list_get_at ($1, 0); - } - else - { - size_t i; - - $$.type = GCONF_TYPE_ARRAY; - $$.v.arg.c = n; - $$.v.arg.v = xcalloc (n, sizeof ($$.v.arg.v[0])); - for (i = 0; i < n; i++) - $$.v.arg.v[i] = *(gconf_value_t *)gl_list_get_at ($1, i); - } - gl_list_free ($1); - } - ; - -vlist : value - { - $$ = simple_list_create (false); - gl_list_add_last ($$, gconf_value_dup (&$1)); - } - | vlist value - { - gl_list_add_last ($1, gconf_value_dup (&$2)); - } - ; - -value : string - { - $$.type = GCONF_TYPE_STRING; - $$.v.string = $1; - } - | list - { - $$.type = GCONF_TYPE_LIST; - $$.v.list = $1; - } - | MSTRING - { - $$.type = GCONF_TYPE_STRING; - $$.v.string = $1; - } - ; - -string : STRING - | IDENT - | slist - ; - -slist : slist0 - { - const void *p; - gl_list_iterator_t itr = gl_list_iterator ($1); - - gconf_line_begin (); - while (gl_list_iterator_next (&itr, &p, NULL)) - gconf_line_add (p, strlen (p)); - $$ = gconf_line_finish (); - gl_list_iterator_free (&itr); - gl_list_free ($1); - } - ; - -slist0 : QSTRING - { - $$ = simple_list_create (false); - gl_list_add_last ($$, $1); - } - | slist0 QSTRING - { - gl_list_add_last ($1, $2); - $$ = $1; - } - ; - -list : '(' ')' - { - $$ = NULL; - } - | '(' values ')' - { - $$ = $2; - } - | '(' values ',' ')' - { - $$ = $2; - } - ; - -values : value - { - $$ = simple_list_create (true); - gl_list_add_last ($$, gconf_value_dup (&$1)); - } - | values ',' value - { - gl_list_add_last ($1, gconf_value_dup (&$3)); - $$ = $1; - } - ; - -opt_sc : /* empty */ - | ';' - ; - -%% - -int -yyerror(char *s) -{ - gconf_error (&gconf_current_locus, 0, "%s", s); - return 0; -} - -static void -listel_dispose(const void *el) -{ - free((void*)el); -} - -static gl_list_t -simple_list_create (bool dispose) -{ - return gl_list_create_empty(&gl_linked_list_implementation, - NULL, - NULL, - dispose ? listel_dispose : NULL, - false); -} - - -void -gconf_warning(gconf_locus_t *locus, int errcode, const char *fmt, ...) -{ - va_list ap; - char *buf = NULL; - - va_start (ap, fmt); - vasprintf (&buf, fmt, ap); - va_end (ap); - gconf_print_diag (locus, 0, errcode, buf); - free(buf); -} - -void -gconf_error (gconf_locus_t *locus, int errcode, const char *fmt, ...) -{ - va_list ap; - char *buf = NULL; - - va_start (ap, fmt); - vasprintf (&buf, fmt, ap); - va_end (ap); - gconf_print_diag (locus, 1, errcode, buf); - free (buf); - gconf_error_count++; -} - -void -gconf_set_keywords (struct gconf_keyword *kwd) -{ - config_keywords.kwd = kwd; -} - -int -gconf_parse (const char *name) -{ - int rc; - if (gconf_lex_begin (name)) - return 1; - cursect = &config_keywords; - if (sections) - { - gl_list_free (sections); - sections = NULL; - } - rc = yyparse (); - gconf_lex_end (); - if (gconf_error_count) - rc = 1; - return rc; -} - -void -gconf_gram_trace (int n) -{ - yydebug = n; -} - - - -static void * -target_ptr (struct gconf_keyword *kwp) -{ - char *base; - - if (kwp->varptr) - base = (char*) kwp->varptr + kwp->offset; - else if (cursect && cursect->callback_data) - base = (char*) cursect->callback_data + kwp->offset; - else - base = NULL; - return base; -} - -static int -fake_callback (enum gconf_callback_command cmd, - gconf_locus_t *locus, - void *varptr, - gconf_value_t *value, - void *cb_data) -{ - return 0; -} - -static struct gconf_keyword fake = { - "*", - NULL, - NULL, - gconf_type_void, - NULL, - 0, - fake_callback, - NULL, - &fake -}; - -static void -stmt_begin (struct gconf_keyword *kwp, gconf_value_t tag) -{ - void *target; - - if (!sections) - sections = simple_list_create (false); - gl_list_add_first (sections, cursect); - if (kwp) - { - target = target_ptr (kwp); - cursect = kwp; - if (kwp->callback && kwp->callback (gconf_callback_section_begin, - &gconf_current_locus, /* FIXME */ - target, - &tag, - &kwp->callback_data)) - cursect = &fake; - } - else - /* install "ignore-all" section */ - cursect = kwp; -} - -static void -stmt_end (struct gconf_keyword *kwp) -{ - gconf_callback_fn callback = NULL; - void *dataptr = NULL; - - if (cursect && cursect->callback) - { - callback = cursect->callback; - dataptr = &cursect->callback_data; - } - - if (gl_list_size (sections) == 0) - abort (); - cursect = (struct gconf_keyword *) gl_list_get_at (sections, 0); - gl_list_remove_at (sections, 0); - if (callback) - callback (gconf_callback_section_end, - &gconf_current_locus, /* FIXME */ - kwp ? target_ptr(kwp) : NULL, - NULL, - dataptr); - -} - -static struct gconf_keyword * -find_keyword (const char *ident) -{ - struct gconf_keyword *kwp; - - if (cursect && cursect != &fake) - { - for (kwp = cursect->kwd; kwp->ident; kwp++) - if (strcmp (kwp->ident, ident) == 0) - return kwp; - } - else - { - return &fake; - } - return NULL; -} - -static int -string_to_signed (intmax_t *sval, const char *string, - intmax_t minval, intmax_t maxval) -{ - intmax_t t; - char *p; - - t = strtoimax (string, &p, 0); - if (*p) - { - gconf_error (&gconf_current_locus, 0, _("cannot convert `%s' to number"), - string); - return 1; - } - else if (t < minval || t > maxval) - { - gconf_error (&gconf_current_locus, 0, - _("%s: value out of allowed range %"PRIiMAX"..%"PRIiMAX), - string, minval, maxval); - return 1; - } - *sval = t; - return 0; -} - -static int -string_to_unsigned (uintmax_t *sval, const char *string, uintmax_t maxval, - gconf_locus_t *loc) -{ - uintmax_t t; - char *p; - - t = strtoumax (string, &p, 0); - if (*p) - { - gconf_error (loc, 0, _("cannot convert `%s' to number"), - string); - return 1; - } - else if (t > maxval) - { - gconf_error (loc, 0, - _("%s: value out of allowed range 0..%"PRIuMAX), - string, maxval); - return 1; - } - *sval = t; - return 0; -} - -static int -string_to_bool (const char *string, int *pval) -{ - if (strcmp (string, "yes") == 0 - || strcmp (string, "true") == 0 - || strcmp (string, "t") == 0 - || strcmp (string, "1") == 0) - *pval = 1; - else if (strcmp (string, "no") == 0 - || strcmp (string, "false") == 0 - || strcmp (string, "nil") == 0 - || strcmp (string, "0") == 0) - *pval = 0; - else - { - gconf_error (&gconf_current_locus, 0, - _("%s: not a valid boolean value"), - string); - return 1; - } - return 0; -} - -static int -string_to_host (struct in_addr *in, const char *string) -{ - if (inet_aton (string, in) == 0) - { - struct hostent *hp; - - hp = gethostbyname (string); - if (hp == NULL) - return 1; - memcpy (in, hp->h_addr, sizeof (struct in_addr)); - } - return 0; -} - -static int -string_to_sockaddr (struct gconf_sockaddr *sp, const char *string) -{ - if (string[0] == '/') - { - struct sockaddr_un s_un; - if (strlen (string) >= sizeof (s_un.sun_path)) - { - gconf_error (&gconf_current_locus, 0, - _("%s: UNIX socket name too long"), - string); - return 1; - } - s_un.sun_family = AF_UNIX; - strcpy (s_un.sun_path, string); - sp->len = sizeof (s_un); - sp->sa = xmalloc (sp->len); - memcpy (sp->sa, &s_un, sp->len); - } - else - { - char *p = strchr (string, ':'); - size_t len; - struct sockaddr_in sa; - - sa.sin_family = AF_INET; - if (p) - len = p - string; - else - len = strlen (string); - - if (len == 0) - sa.sin_addr.s_addr = INADDR_ANY; - else - { - char *host = xmalloc (len + 1); - memcpy (host, string, len); - host[len] = 0; - - if (string_to_host (&sa.sin_addr, host)) - { - gconf_error (&gconf_current_locus, 0, - _("%s: not a valid IP address or hostname"), - host); - free (host); - return 1; - } - free (host); - } - - if (p) - { - struct servent *serv; - - p++; - serv = getservbyname (p, "tcp"); - if (serv != NULL) - sa.sin_port = serv->s_port; - else - { - unsigned long l; - char *q; - - /* Not in services, maybe a number? */ - l = strtoul (p, &q, 0); - - if (*q || l > USHRT_MAX) - { - gconf_error (&gconf_current_locus, 0, - _("%s: not a valid port number"), p); - return 1; - } - sa.sin_port = htons (l); - } - } - else if (gconf_default_port) - sa.sin_port = gconf_default_port; - else - { - gconf_error (&gconf_current_locus, 0, _("missing port number")); - return 1; - } - sp->len = sizeof (sa); - sp->sa = xmalloc (sp->len); - memcpy (sp->sa, &sa, sp->len); - } - return 0; -} - -int -gconf_string_convert (void *target, enum gconf_data_type type, - const char *string) -{ - uintmax_t uval; - intmax_t sval; - - switch (type) - { - case gconf_type_void: - abort (); - - case gconf_type_string: - *(const char**)target = string; - break; - - case gconf_type_short: - if (string_to_signed (&sval, string, SHRT_MIN, SHRT_MAX) == 0) - *(short*)target = sval; - else - return 1; - break; - - case gconf_type_ushort: - if (string_to_unsigned (&uval, string, USHRT_MAX, &gconf_current_locus) == 0) - *(unsigned short*)target = uval; - else - return 1; - break; - - case gconf_type_bool: - return string_to_bool (string, (int*)target); - - case gconf_type_int: - if (string_to_signed (&sval, string, INT_MIN, INT_MAX) == 0) - *(int*)target = sval; - else - return 1; - break; - - case gconf_type_uint: - if (string_to_unsigned (&uval, string, UINT_MAX, &gconf_current_locus) == 0) - *(unsigned int*)target = uval; - else - return 1; - break; - - case gconf_type_long: - if (string_to_signed (&sval, string, LONG_MIN, LONG_MAX) == 0) - *(long*)target = sval; - else - return 1; - break; - - case gconf_type_ulong: - if (string_to_unsigned (&uval, string, ULONG_MAX, &gconf_current_locus) == 0) - *(unsigned long*)target = uval; - else - return 1; - break; - - case gconf_type_size: - if (string_to_unsigned (&uval, string, SIZE_MAX, &gconf_current_locus) == 0) - *(size_t*)target = uval; - else - return 1; - break; - - case gconf_type_intmax: - return string_to_signed ((intmax_t*)target, string, - INTMAX_MIN, INTMAX_MAX); - - case gconf_type_uintmax: - return string_to_unsigned ((uintmax_t*)target, string, UINTMAX_MAX, - &gconf_current_locus); - - case gconf_type_time: - /*FIXME: Use getdate */ - if (string_to_unsigned (&uval, string, (time_t)-1, &gconf_current_locus) == 0) - *(time_t*)target = uval; - else - return 1; - break; - - case gconf_type_ipv4: - if (inet_aton (string, (struct in_addr *)target)) - { - gconf_error (&gconf_current_locus, 0, _("%s: not a valid IP address"), string); - return 1; - } - break; - - case gconf_type_host: - if (string_to_host ((struct in_addr *)target, string)) - { - gconf_error (&gconf_current_locus, 0, - _("%s: not a valid IP address or hostname"), string); - return 1; - } - break; - - case gconf_type_sockaddr: - return string_to_sockaddr ((struct gconf_sockaddr *)target, string); - - /* FIXME: */ - case gconf_type_cidr: - gconf_error (&gconf_current_locus, 0, _("INTERNAL ERROR at %s:%d"), __FILE__, - __LINE__); - abort(); - - case gconf_type_section: - gconf_error (&gconf_current_locus, 0, - _("Invalid use of block statement")); - return 1; - } - return 0; -} - -struct gconf_prop -{ - size_t size; - gl_listelement_equals_fn eqfn; -}; - -static bool -string_eq (const void *elt1, const void *elt2) -{ - return strcmp ((const char *)elt1, (const char *)elt2) == 0; -} - -#define __gconf_name_cat__(a,b) a ## b -#define NUMEQ(type) __gconf_name_cat__(type,_eq) -#define __DECL_NUMEQ(type,ctype) \ - static bool \ - NUMEQ(type) (const void *elt1, const void *elt2) \ - { \ - return memcmp (elt1, elt2, sizeof (ctype)) == 0; \ - } -#define DECL_NUMEQ(type) __DECL_NUMEQ(type,type) - -DECL_NUMEQ(short) -DECL_NUMEQ(int) -DECL_NUMEQ(long) -DECL_NUMEQ(size_t) -DECL_NUMEQ(uintmax_t) -DECL_NUMEQ(intmax_t) -DECL_NUMEQ(time_t) -__DECL_NUMEQ(in_addr, struct in_addr) -__DECL_NUMEQ(gconf_sockaddr, struct gconf_sockaddr) - -struct gconf_prop gconf_prop_tab[] = { - { 0, NULL }, /* gconf_type_void */ - { sizeof (char*), string_eq }, /* gconf_type_string */ - { sizeof (short), NUMEQ (short) }, /* gconf_type_short */ - { sizeof (unsigned short), NUMEQ (short) }, /* gconf_type_ushort */ - { sizeof (int), NUMEQ (int) }, /* gconf_type_int */ - { sizeof (unsigned int), NUMEQ (int) }, /* gconf_type_uint */ - { sizeof (long), NUMEQ (long) }, /* gconf_type_long */ - { sizeof (unsigned long), NUMEQ (long) }, /* gconf_type_ulong */ - { sizeof (size_t), NUMEQ (size_t) }, /* gconf_type_size */ - /* gconf_type_off,*/ - { sizeof (uintmax_t), NUMEQ (uintmax_t) }, /* gconf_type_uintmax */ - { sizeof (intmax_t), NUMEQ (intmax_t) }, /* gconf_type_intmax */ - { sizeof (time_t), NUMEQ (time_t) }, /* gconf_type_time */ - { sizeof (int), NUMEQ (int) }, /* gconf_type_bool */ - { sizeof (struct in_addr), NUMEQ (in_addr) }, /* gconf_type_ipv4 */ - { 0, NULL }, /* FIXME: gconf_type_cidr */ - { sizeof (struct in_addr), NUMEQ (in_addr) }, /* gconf_type_host */ - { sizeof (struct gconf_sockaddr), NUMEQ (gconf_sockaddr) }, - /* gconf_type_sockaddr */ - { 0, NULL } /* gconf_type_section */ -}; -#define gconf_prop_count \ - (sizeof (gconf_prop_tab) / sizeof (gconf_prop_tab[0])) - -static void -process_ident (struct gconf_keyword *kwp, gconf_value_t *value) -{ - void *target; - - if (!kwp) - return; - - target = target_ptr (kwp); - - if (kwp->callback) - kwp->callback (gconf_callback_set_value, - &gconf_current_locus, /* FIXME */ - target, - value, - &kwp->callback_data); - else if (value->type == GCONF_TYPE_ARRAY) - { - gconf_error (&gconf_current_locus, 0, - _("too many arguments to `%s'; missing semicolon?"), - kwp->ident); - return; - } - else if (value->type == GCONF_TYPE_LIST) - { - if (GCONF_IS_LIST (kwp->type)) - { - gl_list_iterator_t itr = gl_list_iterator (value->v.list); - enum gconf_data_type type = GCONF_TYPE (kwp->type); - int num = 1; - const void *p; - gl_list_t list; - size_t size; - - if (type >= gconf_prop_count - || (size = gconf_prop_tab[type].size) == 0) - { - gconf_error (&gconf_current_locus, 0, - _("INTERNAL ERROR at %s:%d: " - "unhandled data type %d"), - __FILE__, __LINE__, type); - abort (); - } - - list = gl_list_create_empty (&gl_linked_list_implementation, - gconf_prop_tab[type].eqfn, - NULL, - listel_dispose, - false); - - while (gl_list_iterator_next (&itr, &p, NULL)) - { - const gconf_value_t *vp = p; - - if (vp->type != GCONF_TYPE_STRING) - gconf_error (&gconf_current_locus, 0, - _("%s: incompatible data type in list item #%d"), - kwp->ident, num); - else if (type == gconf_type_string) - gl_list_add_last (list, vp->v.string); - else - { - void *ptr = xmalloc (size); - if (gconf_string_convert (ptr, type, vp->v.string) == 0) - gl_list_add_last (list, ptr); - else - free (ptr); - } - } - gl_list_iterator_free (&itr); - *(gl_list_t*)target = list; - } - else - { - gconf_error (&gconf_current_locus, 0, - _("incompatible data type for `%s'"), - kwp->ident); - return; - } - } - else if (GCONF_IS_LIST (kwp->type)) - { - gl_list_t list; - enum gconf_data_type type = GCONF_TYPE (kwp->type); - size_t size; - void *ptr; - - if (type >= gconf_prop_count - || (size = gconf_prop_tab[type].size) == 0) - { - gconf_error (&gconf_current_locus, 0, - _("INTERNAL ERROR at %s:%d: unhandled data type %d"), - __FILE__, __LINE__, type); - abort(); - } - - list = gl_list_create_empty (&gl_linked_list_implementation, - gconf_prop_tab[type].eqfn, - NULL, - listel_dispose, - false); - if (type == gconf_type_string) - gl_list_add_last (list, value->v.string); - else - { - ptr = xmalloc (size); - if (gconf_string_convert (ptr, type, value->v.string)) - { - free (ptr); - gl_list_free (list); - return; - } - gl_list_add_last (list, ptr); - } - *(gl_list_t*)target = list; - } - else - gconf_string_convert (target, GCONF_TYPE (kwp->type), value->v.string); -} - diff --git a/gconf/gconf-lex.l b/gconf/gconf-lex.l deleted file mode 100644 index 1379640..0000000 --- a/gconf/gconf-lex.l +++ /dev/null @@ -1,476 +0,0 @@ -/* gconf - General purpose configuration parser. -*- c -*- */ -%{ -/* gconf - General purpose configuration parser. - Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3 of the License, or (at your - option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program. If not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include -#include -#include -#include -#include -#include -#include - -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free -#include -#include -#include - -#if ENABLE_NLS -# include "gettext.h" -# define _(msgid) gettext (msgid) -#else -# define _(msgid) msgid -#endif - -static char *multiline_delimiter; -static size_t multiline_delimiter_len; -static int multiline_unescape; /* Unescape here-document contents */ -static int (*char_to_strip) (char); /* Strip matching characters of each - here-document line */ - -gconf_locus_t gconf_current_locus; /* Input file location */ -/* Line correction. Equals to the number of #line directives inserted into - the input by the preprocessor instance. The external preprocessor, if - any, counts these as input lines and therefore the line numbers in *its* - #line directives are offset by the value of XLINES. - - Uff, running two preprocessors is confusing... -*/ -static size_t xlines; -static struct obstack stk; - -static void multiline_begin (char *); -static void multiline_add (char *); -static char *multiline_strip_tabs (char *text); -static void line_add_unescape_last (char *text, size_t len); -static int ident (void); -static int isemptystr (int off); - -static void parse_line (char *text, gconf_locus_t *ploc, size_t *pxlines); -static void parse_line_cpp (char *text, gconf_locus_t *ploc, size_t *pxlines); - -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - do \ - { \ - if (gconf_preprocessor) \ - result = fread (buf, 1, max_size, yyin); \ - else \ - result = gconf_preproc_fill_buffer(buf, max_size); \ - } \ - while (0) - -%} - - -%x COMMENT ML STR - -WS [ \t\f][ \t\f]* -ID [a-zA-Z_][a-zA-Z_0-9-]+ -P [1-9][0-9]* - -%% - /* C-style comments */ -"/*" BEGIN (COMMENT); -[^*\n]* /* eat anything that's not a '*' */ -"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ -\n ++gconf_current_locus.line; -"*"+"/" BEGIN (INITIAL); - /* Line directive */ -^[ \t]*#[ \t]*{P}[ \t]+\".*\".*\n { parse_line_cpp (yytext, - &gconf_current_locus, - &xlines); } -^[ \t]*#[ \t]*line[ \t].*\n { parse_line (yytext, &gconf_current_locus, - &xlines); } - /* End-of-line comments */ -#.*\n { gconf_current_locus.line++; } -#.* /* end-of-file comment */; -"//".*\n { gconf_current_locus.line++; } -"//".* /* end-of-file comment */; - /* Identifiers */ -{ID} return ident (); - /* Strings */ -[a-zA-Z0-9_\.\*/:@-]+ { gconf_line_begin (); - gconf_line_add (yytext, yyleng); - yylval.string = gconf_line_finish (); - return STRING; } - /* Quoted strings */ -\"[^\\"\n]*\" { gconf_line_begin (); - gconf_line_add (yytext + 1, yyleng - 2); - yylval.string = gconf_line_finish (); - return QSTRING; } -\"[^\\"\n]*\\. | -\"[^\\"\n]*\\\n { BEGIN (STR); - gconf_line_begin (); - line_add_unescape_last (yytext + 1, yyleng - 1); } -[^\\"\n]*\\. | -\"[^\\"\n]*\\\n { line_add_unescape_last (yytext, yyleng); } -[^\\"\n]*\" { BEGIN(INITIAL); - if (yyleng > 1) - gconf_line_add (yytext, yyleng - 1); - yylval.string = gconf_line_finish (); - return QSTRING; } - /* Multiline strings */ -"<<"(-" "?)?\\?{ID}[ \t]*#.*\n | -"<<"(-" "?)?\\?{ID}[ \t]*"//".*\n | -"<<"(-" "?)?\\?{ID}[ \t]*\n | -"<<"(-" "?)?\"{ID}\"[ \t]*#.*\n | -"<<"(-" "?)?\"{ID}\"[ \t]*"//".*\n | -"<<"(-" "?)?\"{ID}\"[ \t]*\n { - BEGIN (ML); - multiline_begin (yytext+2); - gconf_current_locus.line++; } - /* Ignore m4 line statements */ -^"#line ".*\n { gconf_current_locus.line++; } -.*\n { char *p = multiline_strip_tabs (yytext); - - if (!strncmp (p, multiline_delimiter, multiline_delimiter_len) - && isemptystr (p + multiline_delimiter_len - yytext)) - { - free (multiline_delimiter); - multiline_delimiter = NULL; - BEGIN (INITIAL); - yylval.string = gconf_line_finish (); - return MSTRING; - } - gconf_current_locus.line++; - multiline_add (p); } -{WS} ; - /* Other tokens */ -\n { gconf_current_locus.line++; } -[,;{}()] return yytext[0]; -. { if (isascii (yytext[0]) && isprint (yytext[0])) - gconf_error (&gconf_current_locus, 0, _("stray character %c"), yytext[0]); - else - gconf_error (&gconf_current_locus, 0, _("stray character \\%03o"), - (unsigned char) yytext[0]); } -%% - -pid_t gconf_preproc_pid; - -int -yywrap () -{ - if (yyin) - gconf_preproc_extrn_shutdown (gconf_preproc_pid); - else - gconf_preproc_done (); - gconf_current_locus.file = NULL; - return 1; -} - -int -gconf_lex_begin (const char *name) -{ - if (yy_flex_debug > 0) - yy_flex_debug = 0; - obstack_init (&stk); - if (gconf_preprocessor) - { - int fd; - - fd = open (name, O_RDONLY); - if (fd == -1) - { - gconf_error (NULL, errno, _("Cannot open `%s'"), name); - return 1; - } - close (fd); - - yyin = gconf_preproc_extrn_start (name, &gconf_preproc_pid); - if (!yyin) - { - gconf_error (NULL, errno, - _("Unable to start external preprocessor `%s'"), - gconf_preprocessor); - return 1; - } - } - else - return gconf_preproc_init (name); - - return 0; -} - -void -gconf_lex_end () -{ -} - -static int -isemptystr (int off) -{ - for (; yytext[off] && isspace (yytext[off]); off++) - ; - if (yytext[off] == ';') - { - int i; - for (i = off + 1; yytext[i]; i++) - if (!isspace (yytext[i])) - return 0; - yyless (off); - return 1; - } - return yytext[off] == 0; -} - -char * -multiline_strip_tabs (char *text) -{ - if (char_to_strip) - for (; *text && char_to_strip (*text); text++) - ; - return text; -} - -static int -unquote_char (int c) -{ - static char quote_transtab[] = "\\\\a\ab\bf\fn\nr\rt\t"; - - char *p; - - for (p = quote_transtab; *p; p += 2) - { - if (*p == c) - return p[1]; - } - return -1; -} - -static void -unescape_to_obstack (int c) -{ - if (c != '\n') - { - int t = unquote_char (c); - if (t != -1) - obstack_1grow (&stk, t); - else - { - gconf_warning(&gconf_current_locus, 0, - _("unknown escape sequence '\\%c'"), - c); - obstack_1grow (&stk, c); - } - } -} - -void -gconf_line_add (const char *text, size_t len) -{ - obstack_grow (&stk, text, len); -} - -/* Same, but unescapes the last character from yytext */ -static void -line_add_unescape_last (char *text, size_t len) -{ - obstack_grow (&stk, text, len - 2); - unescape_to_obstack (text[len - 1]); -} - -static void -multiline_add (char *s) -{ - if (multiline_unescape) - { - for (; *s; s++) - { - if (*s == '\\') - { - unescape_to_obstack (s[1]); - ++s; - } - else - obstack_1grow (&stk, *s); - } - } - else - gconf_line_add (s, strlen (s)); -} - -void -gconf_line_begin () -{ - /* FIXME: nothing so far. Maybe prepare stk by calling obstack_finish? */ -} - -static int -is_tab (char c) -{ - return c == '\t'; -} - -static int -is_ws (char c) -{ - return c == '\t' || c == ' '; -} - -void -multiline_begin (char *p) -{ - if (*p == '-') - { - if (*++p == ' ') - { - char_to_strip = is_ws; - p++; - } - else - char_to_strip = is_tab; - } - else - char_to_strip = NULL; - if (*p == '\\') - { - p++; - multiline_unescape = 0; - } - else if (*p == '"') - { - char *q; - - p++; - multiline_unescape = 0; - q = strchr (p, '"'); - multiline_delimiter_len = q - p; - } - else - { - multiline_delimiter_len = strcspn (p, " \t"); - multiline_unescape = 1; - } - - /* Remove trailing newline */ - multiline_delimiter_len--; - multiline_delimiter = xmalloc (multiline_delimiter_len + 1); - memcpy (multiline_delimiter, p, multiline_delimiter_len); - multiline_delimiter[multiline_delimiter_len] = 0; - gconf_line_begin (); -} - -char * -gconf_line_finish () -{ - obstack_1grow (&stk, 0); - return obstack_finish (&stk); -} - -static int -ident () -{ - char *p; - - for (p = yytext; *p && isspace (*p); p++) - ; - obstack_grow (&stk, p, strlen (p)); - obstack_1grow (&stk, 0); - yylval.string = obstack_finish (&stk); - return IDENT; -} - -void -gconf_lex_trace (int n) -{ - yy_flex_debug = -n; -} - -gconf_value_t * -gconf_value_dup(gconf_value_t *input) -{ - gconf_value_t *ptr = obstack_alloc (&stk, sizeof (*ptr)); - *ptr = *input; - return ptr; -} - - -static int -assign_locus (gconf_locus_t *ploc, char *name, char *line, size_t *pxlines) -{ - char *p; - - if (name) - { - if (pxlines && (!ploc->file || strcmp(name, ploc->file))) - *pxlines = 0; - ploc->file = gconf_install_text (name); - } - ploc->line = strtoul (line, &p, 10) - (pxlines ? *pxlines : 0); - return *p != 0; -} - -static void -parse_line (char *text, gconf_locus_t *ploc, size_t *pxlines) -{ - int rc = 1; - struct wordsplit ws; - - if (wordsplit (text, &ws, WRDSF_DEFFLAGS)) - gconf_error (ploc, 0, _("cannot parse #line line")); - else - { - if (ws.ws_wordc == 2) - rc = assign_locus (ploc, NULL, ws.ws_wordv[1], pxlines); - else if (ws.ws_wordc == 3) - rc = assign_locus (ploc, ws.ws_wordv[2], ws.ws_wordv[1], pxlines); - else if (ws.ws_wordc == 4) - { - rc = assign_locus (ploc, ws.ws_wordv[2], ws.ws_wordv[1], 0); - if (rc == 0) - { - char *p; - unsigned long x = strtoul (ws.ws_wordv[3], &p, 10); - rc = *p != 0; - if (rc == 0) - *pxlines = x; - } - } - else - gconf_error (ploc, 0, _("invalid #line statement")); - - if (rc) - gconf_error (ploc, 0, _("malformed #line statement")); - wordsplit_free (&ws); - } -} - -static void -parse_line_cpp (char *text, gconf_locus_t *ploc, size_t *pxlines) -{ - struct wordsplit ws; - - if (wordsplit (text, &ws, WRDSF_DEFFLAGS)) - { - gconf_error (ploc, 0, _("cannot parse #line line")); - return; - } - else if (ws.ws_wordc < 3) - gconf_error (ploc, 0, _("invalid #line statement")); - else - { - if (assign_locus (ploc, ws.ws_wordv[2], ws.ws_wordv[1], pxlines)) - gconf_error (ploc, 0, _("malformed #line statement")); - } - wordsplit_free (&ws); -} - diff --git a/gconf/gconf-preproc.c b/gconf/gconf-preproc.c deleted file mode 100644 index 5bd0a95..0000000 --- a/gconf/gconf-preproc.c +++ /dev/null @@ -1,728 +0,0 @@ -/* gconf - General purpose configuration parser. - Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3 of the License, or (at your - option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program. If not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#if ENABLE_NLS -# include "gettext.h" -# define _(msgid) gettext (msgid) -#else -# define _(msgid) msgid -#endif - -bool gconf_log_to_stderr = true; -void (*gconf_log_setup_hook) () = NULL; - -struct input_file_ident -{ - ino_t i_node; - dev_t device; -}; - -struct buffer_ctx -{ - struct buffer_ctx *prev; /* Pointer to previous context */ - gconf_locus_t locus; /* Current input location */ - size_t namelen; /* Length of the file name */ - size_t xlines; /* Number of #line directives output so far */ - struct input_file_ident id; - FILE *infile; -}; - -extern int yy_flex_debug; -static struct buffer_ctx *context_stack; - -#define INFILE context_stack->infile -#define LOCUS context_stack->locus - -static char *linebuf; -static size_t bufsize; -static char *putback_buffer; -static size_t putback_size; -static size_t putback_max; - -static int push_source (const char *name, int once); -static int pop_source (void); -static int parse_include (const char *text, int once); - -static void -putback (const char *str) -{ - size_t len; - - if (!*str) - return; - len = strlen (str) + 1; - if (len > putback_max) - { - putback_max = len; - putback_buffer = xrealloc (putback_buffer, putback_max); - } - strcpy (putback_buffer, str); - putback_size = len - 1; -} - -/* Compute the size of the line - - #line NNN "FILENAME" -*/ -static size_t -pp_line_stmt_size () -{ - char lbuf[INT_BUFSIZE_BOUND(uintmax_t)]; - char xbuf[INT_BUFSIZE_BOUND(uintmax_t)]; - char *lp, *xp; - - lp = umaxtostr (LOCUS.line, lbuf); - xp = umaxtostr (context_stack->xlines + 1, xbuf); - if (context_stack->namelen == 0) - context_stack->namelen = strlen (LOCUS.file); - /* "#line " is 6 chars, two more spaces, two quotes and a linefeed - make another 5, summa facit 11 */ - return 11 + strlen (lp) + strlen (xp) + context_stack->namelen; -} - -static void -pp_line_stmt () -{ - char *p; - size_t ls_size = pp_line_stmt_size (); - size_t pb_size = putback_size + ls_size + 1; - - if (pb_size > putback_max) - { - putback_max = pb_size; - putback_buffer = xrealloc (putback_buffer, putback_max); - } - - p = putback_buffer + putback_size; - context_stack->xlines++; - snprintf (p, putback_max - putback_size, - "#line %lu \"%s\" %lu\n", - (unsigned long) LOCUS.line, - LOCUS.file, (unsigned long) context_stack->xlines); - putback_size += ls_size; -} - -#define STRMATCH(p, len, s) (len >= sizeof(s) \ - && memcmp (p, s, sizeof(s) - 1) == 0 \ - && isspace(p[sizeof(s) - 1])) - -static int -next_line () -{ - ssize_t rc; - - do - { - if (putback_size) - { - if (putback_size + 1 > bufsize) - { - bufsize = putback_size + 1; - linebuf = xrealloc (linebuf, bufsize); - } - strcpy (linebuf, putback_buffer); - rc = putback_size; - putback_size = 0; - } - else if (!context_stack) - return 0; - else - rc = getline (&linebuf, &bufsize, INFILE); - } - while (rc == -1 && pop_source () == 0); - return rc; -} - -size_t -gconf_preproc_fill_buffer (char *buf, size_t size) -{ - size_t bufsize = size; - - while (next_line () > 0) - { - char *p; - size_t len; - int is_line = 0; - - for (p = linebuf; *p && isspace (*p); p++) - ; - if (*p == '#') - { - size_t l; - for (p++; *p && isspace (*p); p++) - ; - l = strlen (p); - if (STRMATCH (p, l, "include_once")) - { - if (parse_include (linebuf, 1)) - putback ("/*include_once*/\n"); - continue; - } - else if (STRMATCH (p, l, "include")) - { - if (parse_include (linebuf, 0)) - putback ("/*include*/\n"); - continue; - } - else if (STRMATCH (p, l, "line")) - is_line = 1; - } - - len = strlen (linebuf); - - if (len > size) - len = size; - - memcpy (buf, linebuf, len); - buf += len; - size -= len; - - if (size == 0) - { - putback (linebuf + len); - break; - } - - if (!is_line && len > 0 && linebuf[len - 1] == '\n') - LOCUS.line++; - } - return bufsize - size; -} - -#define STAT_ID_EQ(st,id) ((id).i_node == (st).st_ino \ - && (id).device == (st).st_dev) - -static struct buffer_ctx * -ctx_lookup (struct stat *st) -{ - struct buffer_ctx *ctx; - - if (!context_stack) - return NULL; - - for (ctx = context_stack->prev; ctx; ctx = ctx->prev) - if (STAT_ID_EQ (*st, ctx->id)) - break; - return ctx; -} - -const char *gconf_preprocessor = NULL; -static gl_list_t include_path; -static gl_list_t std_include_path; - -struct file_data -{ - const char *name; - size_t namelen; - char *buf; - size_t buflen; - int found; -}; - -static int -pp_list_find (gl_list_t list, struct file_data *dptr) -{ - const void *p; - gl_list_iterator_t itr = gl_list_iterator (list); - - while (!dptr->found && gl_list_iterator_next (&itr, &p, NULL)) - { - const char *dir = p; - size_t size = strlen (dir) + 1 + dptr->namelen + 1; - if (size > dptr->buflen) - { - dptr->buflen = size; - dptr->buf = xrealloc (dptr->buf, dptr->buflen); - } - strcpy (dptr->buf, dir); - strcat (dptr->buf, "/"); - strcat (dptr->buf, dptr->name); - dptr->found = access (dptr->buf, F_OK) == 0; - } - gl_list_iterator_free (&itr); - return dptr->found; -} - -gl_list_t -pp_list_create () -{ - return gl_list_create_empty(&gl_linked_list_implementation, - NULL, - NULL, - NULL, - false); -} - -void -gconf_include_path_setup_v (char **dirs) -{ - if (!include_path) - include_path = pp_list_create (); - std_include_path = pp_list_create (); - if (dirs) - { - int i; - for (i = 0; dirs[i]; i++) - /* FIXME: Element never freed */ - gl_list_add_last (std_include_path, xstrdup (dirs[i])); - } -} - -void -gconf_include_path_setup (const char *dir, ...) -{ - const char *p; - char **argv = NULL; - size_t argc = 0; - size_t argi = 0; - va_list ap; - - va_start (ap, dir); - p = dir; - while (1) - { - if (argi == argc) - { - if (argc == 0) - argc = 16; - argv = x2nrealloc (argv, &argc, sizeof (argv[0])); - } - argv[argi++] = (char*) p; - if (!p) - break; - p = va_arg (ap, const char*); - } - gconf_include_path_setup_v (argv); - free (argv); - va_end (ap); -} - -void -gconf_preproc_add_include_dir (char *dir) -{ - if (!include_path) - include_path = pp_list_create (); - gl_list_add_last (include_path, dir); -} - -static Hash_table *incl_sources; - -/* Calculate the hash of a struct input_file_ident. */ -static size_t -incl_hasher (void const *data, unsigned n_buckets) -{ - const struct input_file_ident *id = data; - return (id->i_node + id->device) % n_buckets; -} - -/* Compare two input_file_idents for equality. */ -static bool -incl_compare (void const *data1, void const *data2) -{ - const struct input_file_ident *id1 = data1; - const struct input_file_ident *id2 = data2; - return id1->device == id2->device && id1->i_node == id2->i_node; -} - -static void -incl_free (void *data) -{ - free (data); -} - -static int -source_lookup (struct stat *st) -{ - struct input_file_ident *sample = xmalloc (sizeof (*sample)), *id; - - sample->i_node = st->st_ino; - sample->device = st->st_dev; - - if (!((incl_sources - || (incl_sources = hash_initialize (0, 0, - incl_hasher, - incl_compare, - incl_free))) - && (id = hash_insert (incl_sources, sample)))) - xalloc_die (); - - if (id != sample) - { - free (sample); - return 1; /* Found */ - } - return 0; -} - - -static int -push_source (const char *name, int once) -{ - FILE *fp; - struct buffer_ctx *ctx; - struct stat st; - int rc = stat (name, &st); - - if (context_stack) - { - if (rc) - { - gconf_error (&LOCUS, errno, _("Cannot stat `%s'"), name); - return 1; - } - - if (LOCUS.file && STAT_ID_EQ (st, context_stack->id)) - { - gconf_error (&LOCUS, 0, _("Recursive inclusion")); - return 1; - } - - if ((ctx = ctx_lookup (&st))) - { - gconf_error (&LOCUS, 0, _("Recursive inclusion")); - if (ctx->prev) - gconf_error (&ctx->prev->locus, 0, - _("`%s' already included here"), name); - else - gconf_error (&LOCUS, 0, - _("`%s' already included at top level"), name); - return 1; - } - } - else if (rc) - { - gconf_error (NULL, errno, _("Cannot stat `%s'"), name); - return 1; - } - - if (once && source_lookup (&st)) - return -1; - - fp = fopen (name, "r"); - if (!fp) - { - gconf_error (&LOCUS, errno, _("Cannot open `%s'"), name); - return 1; - } - - /* Push current context */ - ctx = xmalloc (sizeof (*ctx)); - ctx->locus.file = gconf_install_text (name); - ctx->locus.line = 1; - ctx->xlines = 0; - ctx->namelen = strlen (ctx->locus.file); - ctx->id.i_node = st.st_ino; - ctx->id.device = st.st_dev; - ctx->infile = fp; - ctx->prev = context_stack; - context_stack = ctx; - - if (yy_flex_debug) - fprintf (stderr, "Processing file `%s'\n", name); - - pp_line_stmt (); - - return 0; -} - -static int -pop_source () -{ - struct buffer_ctx *ctx; - - if (!context_stack) - return 1; - - fclose (INFILE); - - /* Restore previous context */ - ctx = context_stack->prev; - free (context_stack); - context_stack = ctx; - - if (!context_stack) - { - if (yy_flex_debug) - fprintf (stderr, "End of input\n"); - return 1; - } - - LOCUS.line++; - - if (yy_flex_debug) - fprintf (stderr, "Resuming file `%s' at line %lu\n", - LOCUS.file, (unsigned long) LOCUS.line); - - pp_line_stmt (); - - return 0; -} - -static int -try_file (const char *name, int allow_cwd, int err_not_found, char **newp) -{ - static char *cwd = "."; - struct file_data fd; - - fd.name = name; - fd.namelen = strlen (name); - fd.buf = NULL; - fd.buflen = 0; - fd.found = 0; - - if (!include_path) - gconf_include_path_setup (NULL); - if (allow_cwd) - { - gl_list_node_t node = gl_list_add_last (include_path, cwd); - pp_list_find (include_path, &fd); - gl_list_remove_node (include_path, node); - } - else - pp_list_find (include_path, &fd); - - if (!fd.found) - { - pp_list_find (std_include_path, &fd); - - if (!fd.found && err_not_found) - { - gconf_error (&LOCUS, 0, _("%s: No such file or directory"), name); - *newp = NULL; - } - } - if (fd.found) - *newp = fd.buf; - return fd.found; -} - -static int -parse_include (const char *text, int once) -{ - struct wordsplit ws; - char *tmp = NULL; - char *p = NULL; - int rc = 1; - - if (wordsplit (text, &ws, WRDSF_DEFFLAGS)) - gconf_error (&LOCUS, 0, _("Cannot parse include line")); - else if (ws.ws_wordc != 2) - { - wordsplit_free (&ws); - gconf_error (&LOCUS, 0, _("invalid include statement")); - } - else - { - size_t len; - int allow_cwd; - - p = ws.ws_wordv[1]; - len = strlen (p); - - if (p[0] == '<' && p[len - 1] == '>') - { - allow_cwd = 0; - p[len - 1] = 0; - p++; - } - else - allow_cwd = 1; - - if (p[0] != '/' && try_file (p, allow_cwd, 1, &tmp)) - p = tmp; - } - - if (p) - rc = push_source (p, once); - free (tmp); - wordsplit_free (&ws); - return rc; -} - -int -gconf_preproc_init (const char *name) -{ - return push_source (name, 0); -} - -void -gconf_preproc_done () -{ - if (incl_sources) - hash_free (incl_sources); - free (linebuf); - free (putback_buffer); -} - -int -gconf_preproc_run (const char *config_file, const char *extpp) -{ - size_t i; - char buffer[512]; - - if (gconf_preproc_init (config_file)) - return 1; - if (extpp) - { - FILE *outfile; - char *setup_file; - char *cmd; - - if (try_file ("pp-setup", 1, 0, &setup_file)) - { - asprintf (&cmd, "%s %s -", extpp, setup_file); - free (setup_file); - } - else - cmd = xstrdup (extpp); - //FIXME_DEBUG_F1 (2, "Running preprocessor: `%s'", cmd); - outfile = popen (cmd, "w"); - if (!outfile) - { - gconf_error (NULL, errno, - _("Unable to start external preprocessor `%s'"), cmd); - free (cmd); - return 1; - } - - while ((i = gconf_preproc_fill_buffer (buffer, sizeof buffer))) - fwrite (buffer, 1, i, outfile); - pclose (outfile); - free (cmd); - } - else - { - while ((i = gconf_preproc_fill_buffer (buffer, sizeof buffer))) - fwrite (buffer, 1, i, stdout); - } - gconf_preproc_done (); - return 0; -} - -FILE * -gconf_preproc_extrn_start (const char *file_name, pid_t *ppid) -{ - int pout[2]; - pid_t pid; - int i; - FILE *fp = NULL; - - //FIXME_DEBUG_F1 (2, "Running preprocessor: `%s'", ppcmd); - - pipe (pout); - switch (pid = fork ()) - { - /* The child branch. */ - case 0: - if (pout[1] != 1) - { - close (1); - dup2 (pout[1], 1); - } - - /* Close unneeded descripitors */ - for (i = getdtablesize (); i > 2; i--) - close (i); - - if (!gconf_log_to_stderr) - { - int p[2]; - char *buf = NULL; - size_t size = 0; - FILE *fp; - - signal (SIGCHLD, SIG_DFL); - pipe (p); - switch (pid = fork ()) - { - /* Grandchild */ - case 0: - if (p[1] != 2) - { - close (2); - dup2 (p[1], 2); - } - close (p[0]); - - if (gconf_preproc_run (file_name, gconf_preprocessor)) - exit (127); - exit (0); - - case -1: - /* Fork failed */ - if (gconf_log_setup_hook) - gconf_log_setup_hook (); - gconf_error (NULL, errno, _("Cannot run `%s'"), - gconf_preprocessor); - exit (127); - - default: - /* Sub-master */ - close (p[1]); - fp = fdopen (p[0], "r"); - if (gconf_log_setup_hook) - gconf_log_setup_hook (); - while (getline (&buf, &size, fp) > 0) - gconf_error (NULL, 0, "%s", buf); - } - } - else - { - gconf_preproc_run (file_name, gconf_preprocessor); - } - exit (0); - - case -1: - /* Fork failed */ - gconf_error (NULL, errno, _("Cannot run `%s'"), gconf_preprocessor); - break; - - default: - close (pout[1]); - fp = fdopen (pout[0], "r"); - break; - } - *ppid = pid; - return fp; -} - -void -gconf_preproc_extrn_shutdown (pid_t pid) -{ - int status; - waitpid (pid, &status, 0); -} - diff --git a/gconf/gconf-text.c b/gconf/gconf-text.c deleted file mode 100644 index 0545293..0000000 --- a/gconf/gconf-text.c +++ /dev/null @@ -1,73 +0,0 @@ -/* gconf - General purpose configuration parser. - Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3 of the License, or (at your - option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program. If not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include -#include -#include -#include - -static Hash_table *text_table; - -/* Calculate the hash of a string. */ -static size_t -text_hasher (void const *data, unsigned n_buckets) -{ - return hash_string (data, n_buckets); -} - -/* Compare two strings for equality. */ -static bool -text_compare (void const *data1, void const *data2) -{ - return strcmp (data1, data2) == 0; -} - -static void -text_free (void *data) -{ - free (data); -} - -/* Lookup a text. If it does not exist, create it. */ -char * -gconf_install_text (const char *str) -{ - char *text, *s; - - s = xstrdup (str); - - if (!((text_table - || (text_ta