summaryrefslogtreecommitdiffabout
path: root/gconf/gconf-preproc.c
Side-by-side diff
Diffstat (limited to 'gconf/gconf-preproc.c') (more/less context) (ignore whitespace changes)
-rw-r--r--gconf/gconf-preproc.c728
1 files changed, 0 insertions, 728 deletions
diff --git a/gconf/gconf-preproc.c b/gconf/gconf-preproc.c
deleted file mode 100644
index 5bd0a95..0000000
--- a/gconf/gconf-preproc.c
+++ b/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 <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include <gconf.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-
-#include <xalloc.h>
-#include <hash.h>
-#include <gl_linked_list.h>
-#include <inttostr.h>
-#include <wordsplit.h>
-
-#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);
-}
-

Return to:

Send suggestions and report system problems to the System administrator.