diff options
Diffstat (limited to 'src/preproc.c')
-rw-r--r-- | src/preproc.c | 165 |
1 files changed, 93 insertions, 72 deletions
diff --git a/src/preproc.c b/src/preproc.c index 9cdea3c..a71c93f 100644 --- a/src/preproc.c +++ b/src/preproc.c @@ -29,18 +29,8 @@ #include <errno.h> #include <signal.h> -#include <xalloc.h> -#include <hash.h> -#include <inttostr.h> #include <wordsplit.h> -#if ENABLE_NLS -# include "gettext.h" -# define _(msgid) gettext (msgid) -#else -# define _(msgid) msgid -#endif - int grecs_log_to_stderr = 1; void (*grecs_log_setup_hook) () = NULL; @@ -62,6 +52,8 @@ struct buffer_ctx extern int yy_grecs_flex_debug; static struct buffer_ctx *context_stack; +static char *linebufbase = NULL; +static size_t linebufsize = 0; #define INFILE context_stack->infile #define LOCUS context_stack->locus @@ -76,6 +68,49 @@ static int push_source (const char *name, int once); static int pop_source (void); static int parse_include (const char *text, int once); +static ssize_t +pp_getline (char **pbuf, size_t *psize, FILE *fp) +{ + char *buf = *pbuf; + size_t size = *psize; + ssize_t off = 0; + + do + { + size_t len; + + if (off == size - 1) + { + if (!buf) + { + size = 1; + buf = grecs_malloc (size); + } + else + { + size_t nsize = 2 * size; + if (nsize < size) + grecs_alloc_die (); + buf = grecs_realloc (buf, nsize); + size = nsize; + } + } + if (!fgets (buf + off, size - off, fp)) + { + if (off == 0) + off = -1; + break; + } + off += strlen (buf + off); + } + while (buf[off - 1] != '\n'); + + *pbuf = buf; + *psize = size; + return off; +} + + static void putback (const char *str) { @@ -87,51 +122,34 @@ putback (const char *str) if (len > putback_max) { putback_max = len; - putback_buffer = xrealloc (putback_buffer, putback_max); + putback_buffer = grecs_realloc (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; + size_t ls_size; + size_t pb_size; + + if (grecs_asprintf (&linebufbase, &linebufsize, "#line %lu \"%s\" %lu\n", + (unsigned long) LOCUS.line, + LOCUS.file, (unsigned long) context_stack->xlines)) + grecs_alloc_die (); + + ls_size = strlen (linebufbase); + pb_size = putback_size + ls_size + 1; if (pb_size > putback_max) { putback_max = pb_size; - putback_buffer = xrealloc (putback_buffer, putback_max); + putback_buffer = grecs_realloc (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); + strcpy (putback_buffer + putback_size, linebufbase); putback_size += ls_size; } @@ -151,7 +169,7 @@ next_line () if (putback_size + 1 > bufsize) { bufsize = putback_size + 1; - linebuf = xrealloc (linebuf, bufsize); + linebuf = grecs_realloc (linebuf, bufsize); } strcpy (linebuf, putback_buffer); rc = putback_size; @@ -160,7 +178,7 @@ next_line () else if (!context_stack) return 0; else - rc = getline (&linebuf, &bufsize, INFILE); + rc = pp_getline (&linebuf, &bufsize, INFILE); } while (rc == -1 && pop_source () == 0); return rc; @@ -264,7 +282,7 @@ pp_list_find (struct grecs_list *list, struct file_data *dptr) if (size > dptr->buflen) { dptr->buflen = size; - dptr->buf = xrealloc (dptr->buf, dptr->buflen); + dptr->buf = grecs_realloc (dptr->buf, dptr->buflen); } strcpy (dptr->buf, dir); strcat (dptr->buf, "/"); @@ -285,7 +303,7 @@ grecs_include_path_setup_v (char **dirs) int i; for (i = 0; dirs[i]; i++) /* FIXME: Element never freed */ - grecs_list_append (std_include_path, xstrdup (dirs[i])); + grecs_list_append (std_include_path, grecs_strdup (dirs[i])); } } @@ -306,7 +324,9 @@ grecs_include_path_setup (const char *dir, ...) { if (argc == 0) argc = 16; - argv = x2nrealloc (argv, &argc, sizeof (argv[0])); + else + argc += 16; + argv = grecs_realloc (argv, argc * sizeof (argv[0])); } argv[argi++] = (char*) p; if (!p) @@ -326,23 +346,23 @@ grecs_preproc_add_include_dir (char *dir) grecs_list_append (include_path, dir); } -static Hash_table *incl_sources; +static struct grecs_symtab *incl_sources; /* Calculate the hash of a struct input_file_ident. */ -static size_t -incl_hasher (void const *data, size_t n_buckets) +static unsigned +incl_hasher (void *data, unsigned long 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 +static int 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; + return !(id1->device == id2->device && id1->i_node == id2->i_node); } static void @@ -354,25 +374,26 @@ incl_free (void *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) + struct input_file_ident key; + int install = 1; + + if (!incl_sources) { - free (sample); - return 1; /* Found */ + incl_sources = grecs_symtab_create(sizeof (struct input_file_ident), + incl_hasher, + incl_compare, + NULL, + NULL,/*FIXME: alloc*/ + NULL); + if (!incl_sources) + grecs_alloc_die (); } - return 0; + + key.i_node = st->st_ino; + key.device = st->st_dev; + if (!grecs_symtab_lookup_or_install(incl_sources, &key, &install)) + grecs_alloc_die (); + return !install; } @@ -427,7 +448,7 @@ push_source (const char *name, int once) } /* Push current context */ - ctx = xmalloc (sizeof (*ctx)); + ctx = grecs_malloc (sizeof (*ctx)); ctx->locus.file = grecs_install_text (name); ctx->locus.line = 1; ctx->xlines = 0; @@ -569,10 +590,10 @@ grecs_preproc_init (const char *name) void grecs_preproc_done () { - if (incl_sources) - hash_free (incl_sources); + grecs_symtab_free (incl_sources); free (linebuf); free (putback_buffer); + free (linebufbase); } int @@ -595,7 +616,7 @@ grecs_preproc_run (const char *config_file, const char *extpp) free (setup_file); } else - cmd = xstrdup (extpp); + cmd = grecs_strdup (extpp); /*FIXME_DEBUG_F1 (2, "Running preprocessor: `%s'", cmd);*/ outfile = popen (cmd, "w"); if (!outfile) @@ -683,7 +704,7 @@ grecs_preproc_extrn_start (const char *file_name, pid_t *ppid) fp = fdopen (p[0], "r"); if (grecs_log_setup_hook) grecs_log_setup_hook (); - while (getline (&buf, &size, fp) > 0) + while (pp_getline (&buf, &size, fp) > 0) grecs_error (NULL, 0, "%s", buf); } } |