diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-04-30 12:06:47 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-04-30 12:06:47 +0300 |
commit | bd4a203ab453d78e87e29d11017b35248c9babca (patch) | |
tree | 739ddb735fdfb6aaf668ca1b2ff994004e63d6a0 /src | |
parent | 3f02a6139ea4ed7635453cbcdd600e815a5c2208 (diff) | |
download | grecs-bd4a203ab453d78e87e29d11017b35248c9babca.tar.gz grecs-bd4a203ab453d78e87e29d11017b35248c9babca.tar.bz2 |
Remove dependency on xlists.
* gnulib.modules (linked-list, xlist): Remove.
* src/list.c: New file.
* src/Makefile.am (libgrecs_a_SOURCES): Add list.c
* src/grecs-gram.y: Use grecs_list functions.
* src/preproc.c: Likewise.
* src/grecs.h (grecs_list_entry, grecs_list): New structs.
(grecs_value): use struct grecs_list* for the v.list member.
(grecs_log_to_stderr): Change type to int.
(grecs_list_create, grecs_list_size, grecs_list_push)
(grecs_list_pop, grecs_list_locate, grecs_list_index)
(grecs_list_remove_tail): New protos.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/grecs-gram.y | 181 | ||||
-rw-r--r-- | src/grecs.h | 26 | ||||
-rw-r--r-- | src/list.c | 151 | ||||
-rw-r--r-- | src/preproc.c | 41 |
5 files changed, 274 insertions, 126 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2a12c1a..289373a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,6 +19,7 @@ libgrecs_a_SOURCES = \ format.c\ grecs-gram.y\ grecs-lex.l\ + list.c\ preproc.c\ text.c\ grecs.h\ diff --git a/src/grecs-gram.y b/src/grecs-gram.y index 0fe8443..e36865d 100644 --- a/src/grecs-gram.y +++ b/src/grecs-gram.y @@ -51,7 +51,7 @@ typedef union static struct grecs_keyword config_keywords; static struct grecs_keyword *cursect; #define CURRENT_BASE ((char*)(cursect ? cursect->callback_data : NULL)) -static gl_list_t sections; +static struct grecs_list *sections; int grecs_error_count; int grecs_default_port = 0; @@ -62,13 +62,13 @@ static void stmt_end (struct grecs_keyword *kwp); static struct grecs_keyword *find_keyword (const char *ident); static void process_ident (struct grecs_keyword *kwp, grecs_value_t *value); -static gl_list_t simple_list_create (int dispose); +static struct grecs_list *simple_list_create (int dispose); %} %union { char *string; grecs_value_t value; - gl_list_t list; + struct grecs_list *list; struct grecs_keyword *kw; } @@ -124,32 +124,33 @@ vallist : vlist { size_t n; - if ((n = gl_list_size ($1)) == 1) + if ((n = grecs_list_size ($1)) == 1) { - $$ = *(grecs_value_t *)gl_list_get_at ($1, 0); + $$ = *(grecs_value_t *)grecs_list_index ($1, 0); } else { size_t i; + struct grecs_list_entry *ep; $$.type = GRECS_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] = *(grecs_value_t *)gl_list_get_at ($1, i); + for (i = 0, ep = $1->head; ep; i++, ep = ep->next) + $$.v.arg.v[i] = *(grecs_value_t *)ep->data; } - gl_list_free ($1); + grecs_list_free ($1); } ; vlist : value { $$ = simple_list_create (0); - gl_list_add_last ($$, grecs_value_dup (&$1)); + grecs_list_append ($$, grecs_value_dup (&$1)); } | vlist value { - gl_list_add_last ($1, grecs_value_dup (&$2)); + grecs_list_append ($1, grecs_value_dup (&$2)); } ; @@ -177,26 +178,25 @@ string : STRING slist : slist0 { + struct grecs_list_entry *ep; const void *p; - gl_list_iterator_t itr = gl_list_iterator ($1); - + grecs_line_begin (); - while (gl_list_iterator_next (&itr, &p, NULL)) - grecs_line_add (p, strlen (p)); + for (ep = $1->head; ep; ep = ep->next) + grecs_line_add (ep->data, strlen (ep->data)); $$ = grecs_line_finish (); - gl_list_iterator_free (&itr); - gl_list_free ($1); + grecs_list_free ($1); } ; slist0 : QSTRING { $$ = simple_list_create (0); - gl_list_add_last ($$, $1); + grecs_list_append ($$, $1); } | slist0 QSTRING { - gl_list_add_last ($1, $2); + grecs_list_append ($1, $2); $$ = $1; } ; @@ -218,11 +218,11 @@ list : '(' ')' values : value { $$ = simple_list_create (0); - gl_list_add_last ($$, grecs_value_dup (&$1)); + grecs_list_append ($$, grecs_value_dup (&$1)); } | values ',' value { - gl_list_add_last ($1, grecs_value_dup (&$3)); + grecs_list_append ($1, grecs_value_dup (&$3)); $$ = $1; } ; @@ -241,19 +241,18 @@ yyerror(char *s) } static void -listel_dispose(const void *el) +listel_dispose (void *el) { - free((void*)el); + free (el); } -static gl_list_t +static struct grecs_list * simple_list_create (int dispose) { - return gl_list_create_empty(&gl_linked_list_implementation, - NULL, - NULL, - dispose ? listel_dispose : NULL, - 0); + struct grecs_list *lp = grecs_list_create (); + if (dispose) + lp->free_entry = listel_dispose; + return lp; } @@ -299,7 +298,7 @@ grecs_parse (const char *name) cursect = &config_keywords; if (sections) { - gl_list_free (sections); + grecs_list_free (sections); sections = NULL; } rc = yyparse (); @@ -356,8 +355,8 @@ stmt_begin (struct grecs_keyword *kwp, grecs_value_t tag) void *target; if (!sections) - sections = simple_list_create (0); - gl_list_add_first (sections, cursect); + sections = grecs_list_create (); + grecs_list_push (sections, cursect); if (kwp) { target = target_ptr (kwp, CURRENT_BASE); @@ -386,10 +385,9 @@ stmt_end (struct grecs_keyword *kwp) dataptr = &cursect->callback_data; } - if (gl_list_size (sections) == 0) + cursect = (struct grecs_keyword *) grecs_list_pop (sections); + if (!cursect) abort (); - cursect = (struct grecs_keyword *) gl_list_get_at (sections, 0); - gl_list_remove_at (sections, 0); if (callback) callback (grecs_callback_section_end, &grecs_current_locus, /* FIXME */ @@ -712,54 +710,54 @@ grecs_string_convert (void *target, enum grecs_data_type type, struct grecs_prop { size_t size; - gl_listelement_equals_fn eqfn; + int (*cmp) (const void *, const void *); }; -static bool -string_eq (const void *elt1, const void *elt2) +static int +string_cmp (const void *elt1, const void *elt2) { - return strcmp ((const char *)elt1, (const char *)elt2) == 0; + return strcmp ((const char *)elt1, (const char *)elt2); } #define __grecs_name_cat__(a,b) a ## b -#define NUMEQ(type) __grecs_name_cat__(type,_eq) -#define __DECL_NUMEQ(type,ctype) \ - static bool \ - NUMEQ(type) (const void *elt1, const void *elt2) \ +#define NUMCMP(type) __grecs_name_cat__(type,_cmp) +#define __DECL_NUMCMP(type,ctype) \ + static int \ + NUMCMP(type) (const void *elt1, const void *elt2) \ { \ - return memcmp (elt1, elt2, sizeof (ctype)) == 0; \ + return memcmp (elt1, elt2, sizeof (ctype)); \ } -#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(grecs_sockaddr, struct grecs_sockaddr) +#define DECL_NUMCMP(type) __DECL_NUMCMP(type,type) + +DECL_NUMCMP(short) +DECL_NUMCMP(int) +DECL_NUMCMP(long) +DECL_NUMCMP(size_t) +DECL_NUMCMP(uintmax_t) +DECL_NUMCMP(intmax_t) +DECL_NUMCMP(time_t) +__DECL_NUMCMP(in_addr, struct in_addr) +__DECL_NUMCMP(grecs_sockaddr, struct grecs_sockaddr) struct grecs_prop grecs_prop_tab[] = { { 0, NULL }, /* grecs_type_void */ - { sizeof (char*), string_eq }, /* grecs_type_string */ - { sizeof (short), NUMEQ (short) }, /* grecs_type_short */ - { sizeof (unsigned short), NUMEQ (short) }, /* grecs_type_ushort */ - { sizeof (int), NUMEQ (int) }, /* grecs_type_int */ - { sizeof (unsigned int), NUMEQ (int) }, /* grecs_type_uint */ - { sizeof (long), NUMEQ (long) }, /* grecs_type_long */ - { sizeof (unsigned long), NUMEQ (long) }, /* grecs_type_ulong */ - { sizeof (size_t), NUMEQ (size_t) }, /* grecs_type_size */ + { sizeof (char*), string_cmp }, /* grecs_type_string */ + { sizeof (short), NUMCMP (short) }, /* grecs_type_short */ + { sizeof (unsigned short), NUMCMP (short) }, /* grecs_type_ushort */ + { sizeof (int), NUMCMP (int) }, /* grecs_type_int */ + { sizeof (unsigned int), NUMCMP (int) }, /* grecs_type_uint */ + { sizeof (long), NUMCMP (long) }, /* grecs_type_long */ + { sizeof (unsigned long), NUMCMP (long) }, /* grecs_type_ulong */ + { sizeof (size_t), NUMCMP (size_t) }, /* grecs_type_size */ /* grecs_type_off,*/ - { sizeof (uintmax_t), NUMEQ (uintmax_t) }, /* grecs_type_uintmax */ - { sizeof (intmax_t), NUMEQ (intmax_t) }, /* grecs_type_intmax */ - { sizeof (time_t), NUMEQ (time_t) }, /* grecs_type_time */ - { sizeof (int), NUMEQ (int) }, /* grecs_type_bool */ - { sizeof (struct in_addr), NUMEQ (in_addr) }, /* grecs_type_ipv4 */ + { sizeof (uintmax_t), NUMCMP (uintmax_t) }, /* grecs_type_uintmax */ + { sizeof (intmax_t), NUMCMP (intmax_t) }, /* grecs_type_intmax */ + { sizeof (time_t), NUMCMP (time_t) }, /* grecs_type_time */ + { sizeof (int), NUMCMP (int) }, /* grecs_type_bool */ + { sizeof (struct in_addr), NUMCMP (in_addr) }, /* grecs_type_ipv4 */ { 0, NULL }, /* FIXME: grecs_type_cidr */ - { sizeof (struct in_addr), NUMEQ (in_addr) }, /* grecs_type_host */ - { sizeof (struct grecs_sockaddr), NUMEQ (grecs_sockaddr) }, + { sizeof (struct in_addr), NUMCMP (in_addr) }, /* grecs_type_host */ + { sizeof (struct grecs_sockaddr), NUMCMP (grecs_sockaddr) }, /* grecs_type_sockaddr */ { 0, NULL } /* grecs_type_section */ }; @@ -794,11 +792,10 @@ grecs_process_ident (struct grecs_keyword *kwp, grecs_value_t *value, { if (GRECS_IS_LIST (kwp->type)) { - gl_list_iterator_t itr = gl_list_iterator (value->v.list); + struct grecs_list_entry *ep; enum grecs_data_type type = GRECS_TYPE (kwp->type); int num = 1; - const void *p; - gl_list_t list; + struct grecs_list *list; size_t size; if (type >= grecs_prop_count @@ -811,34 +808,30 @@ grecs_process_ident (struct grecs_keyword *kwp, grecs_value_t *value, abort (); } - list = gl_list_create_empty (&gl_linked_list_implementation, - grecs_prop_tab[type].eqfn, - NULL, - NULL, - 0); - - while (gl_list_iterator_next (&itr, &p, NULL)) + list = grecs_list_create (); + list->cmp = grecs_prop_tab[type].cmp; + + for (ep = value->v.list->head; ep; ep = ep->next) { - const grecs_value_t *vp = p; + const grecs_value_t *vp = ep->data; if (vp->type != GRECS_TYPE_STRING) grecs_error (locus, 0, _("%s: incompatible data type in list item #%d"), kwp->ident, num); else if (type == grecs_type_string) - gl_list_add_last (list, vp->v.string); + grecs_list_append (list, (void*) vp->v.string); else { void *ptr = xmalloc (size); if (grecs_string_convert (ptr, type, vp->v.string, locus) == 0) - gl_list_add_last (list, ptr); + grecs_list_append (list, ptr); else free (ptr); } } - gl_list_iterator_free (&itr); - *(gl_list_t*)target = list; + *(struct grecs_list**)target = list; } else { @@ -850,7 +843,7 @@ grecs_process_ident (struct grecs_keyword *kwp, grecs_value_t *value, } else if (GRECS_IS_LIST (kwp->type)) { - gl_list_t list; + struct grecs_list *list; enum grecs_data_type type = GRECS_TYPE (kwp->type); size_t size; void *ptr; @@ -863,26 +856,24 @@ grecs_process_ident (struct grecs_keyword *kwp, grecs_value_t *value, __FILE__, __LINE__, type); abort(); } - - list = gl_list_create_empty (&gl_linked_list_implementation, - grecs_prop_tab[type].eqfn, - NULL, - listel_dispose, - 0); + + list = grecs_list_create (); + list->cmp = grecs_prop_tab[type].cmp; + list->free_entry = listel_dispose; if (type == grecs_type_string) - gl_list_add_last (list, value->v.string); + grecs_list_append (list, value->v.string); else { ptr = xmalloc (size); if (grecs_string_convert (ptr, type, value->v.string, locus)) { free (ptr); - gl_list_free (list); + grecs_list_free (list); return; } - gl_list_add_last (list, ptr); + grecs_list_append (list, ptr); } - *(gl_list_t*)target = list; + *(struct grecs_list**)target = list; } else grecs_string_convert (target, GRECS_TYPE (kwp->type), value->v.string, diff --git a/src/grecs.h b/src/grecs.h index 3fc01f2..42ef01e 100644 --- a/src/grecs.h +++ b/src/grecs.h @@ -18,8 +18,6 @@ #include <unistd.h> #include <stdlib.h> #include <stdio.h> -#include <gl_xlist.h> -#include <gl_linked_list.h> typedef struct { char *file; @@ -65,10 +63,22 @@ enum grecs_callback_command { #define GRECS_TYPE_LIST 1 #define GRECS_TYPE_ARRAY 2 +struct grecs_list_entry { + struct grecs_list_entry *next; + void *data; +}; + +struct grecs_list { + struct grecs_list_entry *head, *tail; + size_t count; + int (*cmp)(const void *, const void *); + void (*free_entry)(void *); +}; + typedef struct grecs_value { int type; union { - gl_list_t list; + struct grecs_list *list; const char *string; struct { size_t c; @@ -134,7 +144,7 @@ extern int grecs_error_count; extern int grecs_default_port; extern const char *grecs_preprocessor; -extern bool grecs_log_to_stderr; +extern int grecs_log_to_stderr; extern void (*grecs_log_setup_hook) (); size_t grecs_preproc_fill_buffer (char *buf, size_t size); @@ -164,4 +174,12 @@ void grecs_format_statement_array (FILE *stream, struct grecs_keyword *kwp, unsigned level); +struct grecs_list *grecs_list_create (void); +size_t grecs_list_size (struct grecs_list *lp); +void grecs_list_append (struct grecs_list *lp, void *val); +void grecs_list_push (struct grecs_list *lp, void *val); +void *grecs_list_pop (struct grecs_list *lp); +void *grecs_list_locate (struct grecs_list *lp, void *data); +void *grecs_list_index (struct grecs_list *lp, size_t idx); +void *grecs_list_remove_tail (struct grecs_list *lp); diff --git a/src/list.c b/src/list.c new file mode 100644 index 0000000..d2edf73 --- /dev/null +++ b/src/list.c @@ -0,0 +1,151 @@ +/* grecs - Gray's Extensible Configuration System + Copyright (C) 2007, 2008, 2009, 2010 Sergey Poznyakoff + + Grecs 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. + + Grecs 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 Grecs. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <grecs.h> +#include <grecs-gram.h> +#include <stdlib.h> +#include <xalloc.h> + +struct grecs_list * +grecs_list_create () +{ + return xcalloc (1, sizeof (struct grecs_list)); +} + +size_t +grecs_list_size (struct grecs_list *lp) +{ + return lp ? lp->count : 0; +} + +void +grecs_list_append (struct grecs_list *lp, void *val) +{ + struct grecs_list_entry *ep = xmalloc (sizeof (*ep)); + ep->data = val; + ep->next = NULL; + if (lp->tail) + lp->tail->next = ep; + else + lp->head = ep; + lp->tail = ep; + lp->count++; +} + +void +grecs_list_push (struct grecs_list *lp, void *val) +{ + struct grecs_list_entry *ep = xmalloc (sizeof (*ep)); + ep->data = val; + ep->next = lp->head; + lp->head = ep; + lp->count++; +} + +void * +grecs_list_pop (struct grecs_list *lp) +{ + void *data; + struct grecs_list_entry *ep = lp->head; + if (ep) + { + data = ep->data; + lp->head = ep->next; + if (!lp->head) + lp->tail = NULL; + lp->count--; + free (ep); + } + else + data = NULL; + return data; +} + +void +grecs_list_free (struct grecs_list *lp) +{ + struct grecs_list_entry *ep = lp->head; + + while (ep) + { + struct grecs_list_entry *next = ep->next; + if (lp->free_entry) + lp->free_entry (ep->data); + free (ep); + ep = next; + } + free (lp); +} + +static int +_ptrcmp (const void *a, const void *b) +{ + return a != b; +} + +void * +grecs_list_locate (struct grecs_list *lp, void *data) +{ + struct grecs_list_entry *ep; + int (*cmp)(const void *, const void *) = lp->cmp ? lp->cmp : _ptrcmp; + + for (ep = lp->head; ep; ep = ep->next) + { + if (cmp (ep->data, data) == 0) + return ep->data; + } + return NULL; +} + +void * +grecs_list_index (struct grecs_list *lp, size_t idx) +{ + struct grecs_list_entry *ep; + + for (ep = lp->head; ep && idx; ep = ep->next, idx--) + ; + return ep ? ep->data : NULL; +} + +void * +grecs_list_remove_tail (struct grecs_list *lp) +{ + void *data; + + if (!lp->head) + return NULL; + data = lp->tail; + if (lp->head == lp->tail) + { + free (lp->tail); + lp->head = lp->tail = NULL; + lp->count = 0; + } + else + { + struct grecs_list_entry *ep; + + for (ep = lp->head; ep->next != lp->tail; ep = ep->next) + ; + free (lp->tail); + ep->next = NULL; + lp->tail = ep; + } + return data; +} diff --git a/src/preproc.c b/src/preproc.c index 0723a2e..9cdea3c 100644 --- a/src/preproc.c +++ b/src/preproc.c @@ -31,7 +31,6 @@ #include <xalloc.h> #include <hash.h> -#include <gl_linked_list.h> #include <inttostr.h> #include <wordsplit.h> @@ -42,7 +41,7 @@ # define _(msgid) msgid #endif -bool grecs_log_to_stderr = 1; +int grecs_log_to_stderr = 1; void (*grecs_log_setup_hook) () = NULL; struct input_file_ident @@ -241,8 +240,8 @@ ctx_lookup (struct stat *st) } const char *grecs_preprocessor = NULL; -static gl_list_t include_path; -static gl_list_t std_include_path; +static struct grecs_list *include_path; +static struct grecs_list *std_include_path; struct file_data { @@ -254,14 +253,13 @@ struct file_data }; static int -pp_list_find (gl_list_t list, struct file_data *dptr) +pp_list_find (struct grecs_list *list, struct file_data *dptr) { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (list); + struct grecs_list_entry *ep; - while (!dptr->found && gl_list_iterator_next (&itr, &p, NULL)) + for (ep = list->head; !dptr->found && ep; ep = ep->next) { - const char *dir = p; + const char *dir = ep->data; size_t size = strlen (dir) + 1 + dptr->namelen + 1; if (size > dptr->buflen) { @@ -273,32 +271,21 @@ pp_list_find (gl_list_t list, struct file_data *dptr) 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 grecs_include_path_setup_v (char **dirs) { if (!include_path) - include_path = pp_list_create (); - std_include_path = pp_list_create (); + include_path = grecs_list_create (); + std_include_path = grecs_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])); + grecs_list_append (std_include_path, xstrdup (dirs[i])); } } @@ -335,8 +322,8 @@ void grecs_preproc_add_include_dir (char *dir) { if (!include_path) - include_path = pp_list_create (); - gl_list_add_last (include_path, dir); + include_path = grecs_list_create (); + grecs_list_append (include_path, dir); } static Hash_table *incl_sources; @@ -508,9 +495,9 @@ try_file (const char *name, int allow_cwd, int err_not_found, char **newp) grecs_include_path_setup (NULL); if (allow_cwd) { - gl_list_node_t node = gl_list_add_last (include_path, cwd); + grecs_list_append (include_path, cwd); pp_list_find (include_path, &fd); - gl_list_remove_node (include_path, node); + grecs_list_remove_tail (include_path); } else pp_list_find (include_path, &fd); |