From 8e541ddaffcab6eaa36faf86304b51a0bc6a92a1 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Thu, 21 Jan 2016 17:25:55 +0200 Subject: Split declarations between several header files. * Makefile.am (SUBDIRS): Add include * am/grecs.m4 (GRECS_INCLUDES): Update (GRECS_COND_BUILD_INSTALL) (GRECS_COND_BUILD_SHARED) (GRECS_COND_BUILD_STATIC): New conditions. Build include/Makefile and include/grecs/Makefile. * configure.ac: Use src/grecs-gram.y as a source validity marker * include/Makefile.a: New file. * src/grecs.hin: Remove. Split into include/*. See below. * include/grecs.h: New file. * include/grecs/.gitignore: New file. * include/grecs/Makefile.am: New file. * include/grecs/doc.h: New file. * include/grecs/error.h: New file. * include/grecs/format.h: New file. * include/grecs/lex.h: New file. * include/grecs/list.h: New file. * include/grecs/mem.h: New file. * include/grecs/node.h: New file. * include/grecs/parser.h: New file. * include/grecs/preproc.h: New file. * include/grecs/sockaddr.h: New file. * include/grecs/symtab.h: New file. * include/grecs/table.h: New file. * include/grecs/tree.h: New file. * include/grecs/txtacc.h: New file. * include/grecs/types.h.in: New file. * include/grecs/util.h: New file. * include/grecs/value.h: New file. * include/grecs/version.h: New file. * src/grecs-locus.h: Move to ... * include/grecs/locus.h: ... here * src/grecsopt.h: Move to ... * include/grecs/opt.h: ... here * src/json.h: Move to ... * include/grecs/json.h: ... here * src/wordsplit.h: Move to ... * include/wordsplit.h: ... here * src/Make-inst.am (include_HEADERS): Remove. * src/Make-shared.am (grecsinclude_HEADERS) (noinst_HEADERS): Remove. * src/Make-static.am (noinst_HEADERS): Remove. * src/Make.am: Remove header-related stuff * src/bind-gram.y: Fix includes. * src/bind-lex.l: Likewise. * src/cidr.c: Likewise. * src/dhcpd-gram.y: Likewise. * src/dhcpd-lex.l: Likewise. * src/diag.c: Likewise. * src/format.c: Likewise. * src/grecs-gram.y: Likewise. * src/grecs-lex.l: Likewise. * src/json-gram.y: Likewise. * src/json-lex.l: Likewise. * src/jsonfmt.c: Likewise. * src/lookup.c: Likewise. * src/meta1-gram.y: Likewise. * src/meta1-lex.l: Likewise. * src/opthelp.c: Likewise. * src/preproc.c: Likewise. * src/sockaddr.c: Likewise. * src/txtacc.c: Likewise. * src/version.c: Likewise. * tests/gcfenum.c: Likewise. * tests/gcffmt.c: Likewise. * tests/gcfpeek.c: Likewise. * tests/gcfset.c: Likewise. * tests/gcfver.c: Likewise. * tests/json.c: Likewise. --- Makefile.am | 2 +- am/grecs.m4 | 16 +- configure.ac | 2 +- include/Makefile.am | 19 ++ include/grecs.h | 40 ++++ include/grecs/.gitignore | 1 + include/grecs/Makefile.am | 43 ++++ include/grecs/doc.h | 32 +++ include/grecs/error.h | 38 +++ include/grecs/format.h | 62 +++++ include/grecs/json.h | 99 ++++++++ include/grecs/lex.h | 51 ++++ include/grecs/list.h | 55 +++++ include/grecs/locus.h | 80 +++++++ include/grecs/mem.h | 33 +++ include/grecs/node.h | 62 +++++ include/grecs/opt.h | 58 +++++ include/grecs/parser.h | 53 +++++ include/grecs/preproc.h | 46 ++++ include/grecs/sockaddr.h | 66 ++++++ include/grecs/symtab.h | 52 +++++ include/grecs/table.h | 98 ++++++++ include/grecs/tree.h | 71 ++++++ include/grecs/txtacc.h | 36 +++ include/grecs/types.h.in | 24 ++ include/grecs/util.h | 26 +++ include/grecs/value.h | 52 +++++ include/grecs/version.h | 40 ++++ include/wordsplit.h | 250 ++++++++++++++++++++ src/Make-inst.am | 1 - src/Make-shared.am | 6 - src/Make-static.am | 1 - src/Make.am | 14 +- src/bind-gram.y | 1 - src/bind-lex.l | 1 - src/cidr.c | 1 + src/dhcpd-gram.y | 1 - src/dhcpd-lex.l | 1 - src/diag.c | 1 - src/format.c | 2 +- src/grecs-gram.y | 1 - src/grecs-lex.l | 1 - src/grecs-locus.h | 57 ----- src/grecs.hin | 584 ---------------------------------------------- src/grecsopt.h | 58 ----- src/json-gram.y | 4 +- src/json-lex.l | 3 +- src/json.h | 99 -------- src/jsonfmt.c | 3 +- src/lookup.c | 3 +- src/meta1-gram.y | 1 - src/meta1-lex.l | 1 - src/opthelp.c | 2 +- src/preproc.c | 3 +- src/sockaddr.c | 1 + src/txtacc.c | 3 +- src/version.c | 1 + src/wordsplit.h | 250 -------------------- tests/gcfenum.c | 1 + tests/gcffmt.c | 1 + tests/gcfpeek.c | 1 + tests/gcfset.c | 1 + tests/gcfver.c | 1 + tests/json.c | 3 +- 64 files changed, 1529 insertions(+), 1091 deletions(-) create mode 100644 include/Makefile.am create mode 100644 include/grecs.h create mode 100644 include/grecs/.gitignore create mode 100644 include/grecs/Makefile.am create mode 100644 include/grecs/doc.h create mode 100644 include/grecs/error.h create mode 100644 include/grecs/format.h create mode 100644 include/grecs/json.h create mode 100644 include/grecs/lex.h create mode 100644 include/grecs/list.h create mode 100644 include/grecs/locus.h create mode 100644 include/grecs/mem.h create mode 100644 include/grecs/node.h create mode 100644 include/grecs/opt.h create mode 100644 include/grecs/parser.h create mode 100644 include/grecs/preproc.h create mode 100644 include/grecs/sockaddr.h create mode 100644 include/grecs/symtab.h create mode 100644 include/grecs/table.h create mode 100644 include/grecs/tree.h create mode 100644 include/grecs/txtacc.h create mode 100644 include/grecs/types.h.in create mode 100644 include/grecs/util.h create mode 100644 include/grecs/value.h create mode 100644 include/grecs/version.h create mode 100644 include/wordsplit.h delete mode 100644 src/grecs-locus.h delete mode 100644 src/grecs.hin delete mode 100644 src/grecsopt.h delete mode 100644 src/json.h delete mode 100644 src/wordsplit.h diff --git a/Makefile.am b/Makefile.am index e499bb4..3eaa8df 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,7 @@ # along with Grecs. If not, see . ACLOCAL_AMFLAGS = -I am -SUBDIRS=. src @GRECS_TESTDIR@ @GRECS_DOCDIR@ +SUBDIRS=. include src @GRECS_TESTDIR@ @GRECS_DOCDIR@ EXTRA_DIST=build-aux/yyrename @GRECS_BUILD_AUX@ @GRECS_DISTDOC@ gitid.h noinst_HEADERS = gitid.h diff --git a/am/grecs.m4 b/am/grecs.m4 index 74b7840..60244a1 100644 --- a/am/grecs.m4 +++ b/am/grecs.m4 @@ -202,13 +202,14 @@ AC_DEFUN([GRECS_SETUP],[ AC_SUBST([GRECS_CHANGELOG]) AC_SUBST([GRECS_DISTCK_AT]) AC_SUBST([GRECS_README]) - AC_SUBST([GRECS_INCLUDES],['-I$(top_srcdir)/]grecsdir[src] [-I$(top_builddir)/]grecsdir[src]') + AC_SUBST([GRECS_INCLUDES],['-I$(top_srcdir)/]grecsdir[include] [-I$(top_builddir)/]grecsdir[include]') AC_SUBST([GRECS_HOST_PROJECT_INCLUDES]) AC_SUBST([GRECS_DISTDOC]) AC_SUBST([GRECS_INCLUDE_DIR],['$(pkgincludedir)']) - + _GRECS_OPTION_SWITCH([install],[ LT_INIT + GRECS_BUILD_TYPE=install GRECS_LDADD=['$(top_builddir)/]grecsdir[src/libgrecs.la'] GRECS_DOCDIR='doc' GRECS_CHANGELOG= @@ -218,18 +219,27 @@ AC_DEFUN([GRECS_SETUP],[ grecsdir[doc/Makefile]) ],[shared],[ LT_INIT + GRECS_BUILD_TYPE=shared GRECS_LDADD=['$(top_builddir)/]grecsdir[src/libgrecs.la'] GRECS_CHANGELOG='#' GRECS_README=README.submodule _GRECS_IF_OPTION_SET([syntax-doc],[GRECS_DISTDOC=doc/grecs-syntax.texi]) AC_CONFIG_FILES(grecsdir[src/Makefile]:grecsdir[src/Make-shared.in]) ],[ + GRECS_BUILD_TYPE=static GRECS_LDADD=['$(top_builddir)/]grecsdir[src/libgrecs.a'] GRECS_CHANGELOG='#' GRECS_README=README.submodule _GRECS_IF_OPTION_SET([syntax-doc],[GRECS_DISTDOC=doc/grecs-syntax.texi]) AC_CONFIG_FILES(grecsdir[src/Makefile]:grecsdir[src/Make-static.in]) ]) - AC_CONFIG_FILES(grecsdir[Makefile] grecsdir[src/grecs.h]:grecsdir[src/grecs.hin]) + AM_CONDITIONAL([GRECS_COND_BUILD_INSTALL],[test $GRECS_BUILD_TYPE = install]) + AM_CONDITIONAL([GRECS_COND_BUILD_SHARED],[test $GRECS_BUILD_TYPE = shared]) + AM_CONDITIONAL([GRECS_COND_BUILD_STATIC],[test $GRECS_BUILD_TYPE = static]) + + AC_CONFIG_FILES(grecsdir[Makefile] + grecsdir[include/Makefile] + grecsdir[include/grecs/Makefile] + grecsdir[include/grecs/types.h]:grecsdir[include/grecs/types.h.in]) m4_popdef([grecsdir]) ]) diff --git a/configure.ac b/configure.ac index b923c9b..6ffa55b 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ AC_PREREQ(2.63) AC_INIT([libgrecs], [1.0], [gray+grecs@gnu.org.ua]) -AC_CONFIG_SRCDIR([src/grecs.hin]) +AC_CONFIG_SRCDIR([src/grecs-gram.y]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE([1.11 gnu tar-ustar dist-xz std-options silent-rules]) diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..21a51e7 --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,19 @@ +SUBDIRS = grecs +GRECS_HDR = grecs.h wordsplit.h + +if GRECS_COND_BUILD_INSTALL + include_HEADERS = $(GRECS_HDR) +endif + +if GRECS_COND_BUILD_SHARED + if GRECS_COND_INSTALLHEADERS + grecsincludedir = @GRECS_INCLUDE_DIR@ + grecsinclude_HEADERS = $(GRECS_HDR) + else + noinst_HEADERS = $(GRECS_HDR) + endif +endif + +if GRECS_COND_BUILD_STATIC + noinst_HEADERS = $(GRECS_HDR) +endif diff --git a/include/grecs.h b/include/grecs.h new file mode 100644 index 0000000..eac11d4 --- /dev/null +++ b/include/grecs.h @@ -0,0 +1,40 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_H +#define _GRECS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/include/grecs/.gitignore b/include/grecs/.gitignore new file mode 100644 index 0000000..8cb8a05 --- /dev/null +++ b/include/grecs/.gitignore @@ -0,0 +1 @@ +types.h diff --git a/include/grecs/Makefile.am b/include/grecs/Makefile.am new file mode 100644 index 0000000..c239c1b --- /dev/null +++ b/include/grecs/Makefile.am @@ -0,0 +1,43 @@ +GRECS_PKG_HDR =\ + doc.h\ + error.h\ + format.h\ + lex.h\ + list.h\ + locus.h\ + mem.h\ + node.h\ + opt.h\ + parser.h\ + preproc.h\ + sockaddr.h\ + symtab.h\ + table.h\ + tree.h\ + txtacc.h\ + types.h\ + util.h\ + value.h\ + version.h + +if GRECS_COND_JSON + GRECS_PKG_HDR += json.h +endif + +if GRECS_COND_BUILD_INSTALL + grecsincludedir = @GRECS_INCLUDE_DIR@ + grecsinclude_HEADERS = $(GRECS_PKG_HDR) +endif + +if GRECS_COND_BUILD_SHARED + if GRECS_COND_INSTALLHEADERS + grecsincludedir = @GRECS_INCLUDE_DIR@ + grecsinclude_HEADERS = $(GRECS_PKG_HDR) + else + noinst_HEADERS = $(GRECS_PKG_HDR) + endif +endif + +if GRECS_COND_BUILD_STATIC + noinst_HEADERS = $(GRECS_PKG_HDR) +endif diff --git a/include/grecs/doc.h b/include/grecs/doc.h new file mode 100644 index 0000000..b2514fb --- /dev/null +++ b/include/grecs/doc.h @@ -0,0 +1,32 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_DOC_H +#define _GRECS_DOC_H + +#include +#include + +void grecs_print_docstring(const char *docstring, unsigned level, + FILE *stream); +void grecs_print_simple_statement(struct grecs_keyword *kwp, + unsigned level, FILE *stream); +void grecs_print_block_statement(struct grecs_keyword *kwp, + unsigned level, FILE *stream); +void grecs_print_statement_array(struct grecs_keyword *kwp, + unsigned n, + unsigned level, FILE *stream); +#endif diff --git a/include/grecs/error.h b/include/grecs/error.h new file mode 100644 index 0000000..8630b8a --- /dev/null +++ b/include/grecs/error.h @@ -0,0 +1,38 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_ERROR_H +#define _GRECS_ERROR_H + +#include + +extern int grecs_log_to_stderr; +extern void (*grecs_log_setup_hook)(void); + +extern void (*grecs_print_diag_fun)(grecs_locus_t const *, int, int, + const char*); + +void grecs_warning(grecs_locus_t const *locus, + int errcode, const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); +void grecs_error(grecs_locus_t const *locus, int errcode, + const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); + +int grecs_asprint_locus(char **locstr, size_t *size, + grecs_locus_t const *locus); + +#endif diff --git a/include/grecs/format.h b/include/grecs/format.h new file mode 100644 index 0000000..7ac8458 --- /dev/null +++ b/include/grecs/format.h @@ -0,0 +1,62 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_FORMAT_H +#define _GRECS_FORMAT_H + +#include +#include +#include +#include + +struct grecs_format_closure { + int (*fmtfun)(const char *, void *); + void *data; +}; + +void grecs_format_locus(grecs_locus_t *locus, struct grecs_format_closure *fp); +void grecs_format_node_path(struct grecs_node *node, int flag, + struct grecs_format_closure *fp); +void grecs_format_value(struct grecs_value *val, int flags, + struct grecs_format_closure *fp); + +#define GRECS_NODE_FLAG_PATH 0x00100 +#define GRECS_NODE_FLAG_VALUE 0x00200 +#define GRECS_NODE_FLAG_DESCEND 0x01000 +#define GRECS_NODE_FLAG_LOCUS 0x02000 +#define GRECS_NODE_FLAG_QUOTE 0x04000 +#define GRECS_NODE_FLAG_NOQUOTE 0x08000 +#define GRECS_NODE_FLAG_QUOTE_HEX 0x10000 + +#define _GRECS_NODE_MASK_DELIM 0x000ff +#define _GRECS_NODE_MASK_OUTPUT 0x00f00 + +#define GRECS_NODE_FLAG_DEFAULT \ + (GRECS_NODE_FLAG_PATH|GRECS_NODE_FLAG_VALUE|\ + GRECS_NODE_FLAG_DESCEND|GRECS_NODE_FLAG_QUOTE) +int grecs_format_node(struct grecs_node *node, int flags, + struct grecs_format_closure *fp); + +void grecs_print_locus(grecs_locus_t *locus, FILE *fp); +void grecs_print_node_path(struct grecs_node *node, int flag, FILE *fp); +void grecs_print_value(struct grecs_value *val, int flags, FILE *fp); + +int grecs_print_node(struct grecs_node *node, int flags, FILE *fp); + +void grecs_txtacc_format_value(struct grecs_value *val, int flags, + grecs_txtacc_t acc); + +#endif diff --git a/include/grecs/json.h b/include/grecs/json.h new file mode 100644 index 0000000..f8402e7 --- /dev/null +++ b/include/grecs/json.h @@ -0,0 +1,99 @@ +/* This file is part of Grecs. + Copyright (C) 2012-2016 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, 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 . */ + +#include + +enum json_value_type +{ + json_null, + json_bool, + json_number, + json_string, + json_arr, + json_object +}; + +struct json_value; +struct json_array { + size_t oc; + struct json_value **ov; + struct grecs_list *ol; +}; + +struct json_value { + enum json_value_type type; + union { + int b; /* json_bool */ + double n; /* json_number */ + char *s; /* json_string */ + struct json_array *a; /* json_arr */ + struct grecs_symtab *o; /* json_object */ + } v; +}; + +struct json_pair { + char *k; + struct json_value *v; +}; + +extern char const *json_err_diag; +extern struct grecs_locus json_err_locus; +extern struct json_value *json_return_obj; + +void jsonlex_setup(char const *s, size_t l); +void jsonlex_diag(const char *s); +int json_unescape(char c, char *o); + +struct json_value *json_value_create(int type); +struct grecs_symtab *json_assoc_create(void); +void json_value_free(struct json_value *obj); + +struct json_value *json_parse_string(char const *input, size_t len); + +struct json_value *json_value_lookup(struct json_value *obj, + const char *ident); + + +struct json_format +{ + size_t indent; + int precision; + void (*write) (void *, char const *, size_t); + void *data; +}; + +void json_format_value(struct json_value *obj, struct json_format *fmt); + +struct json_value *json_new_null(void); +struct json_value *json_new_bool(int b); +struct json_value *json_new_number(double n); +struct json_value *json_new_string(char const *str); + +struct json_value *json_new_object(void); +int json_object_set(struct json_value *obj, char const *name, + struct json_value *val); +int json_object_get(struct json_value *obj, char const *name, + struct json_value **retval); + +struct json_value *json_new_array(void); +size_t json_array_size(struct json_value *j); +void json_array_flatten(struct json_value *j); +int json_array_insert(struct json_value *j, size_t idx, struct json_value *v); +int json_array_append(struct json_value *j, struct json_value *v); +int json_array_set(struct json_value *j, size_t idx, struct json_value *v); +int json_array_get(struct json_value *j, size_t idx, + struct json_value **retval); + diff --git a/include/grecs/lex.h b/include/grecs/lex.h new file mode 100644 index 0000000..fe2365f --- /dev/null +++ b/include/grecs/lex.h @@ -0,0 +1,51 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_LEX_H +#define _GRECS_LEX_H + +int grecs_lex_begin(const char*, int); +void grecs_lex_end(int err); + +char *grecs_install_text(const char *str); +void grecs_destroy_text(void); +struct grecs_symtab *grecs_text_table(void); + +void grecs_parse_line_directive(char *text, grecs_locus_t *ploc, + struct grecs_locus_point *ppoint, + size_t *pxlines); +void grecs_parse_line_directive_cpp(char *text, grecs_locus_t *ploc, + struct grecs_locus_point *ppoint, + size_t *pxlines); + +void grecs_line_acc_create(void); +void grecs_line_acc_free(void); +void grecs_line_acc_grow_char(int c); +void grecs_line_acc_grow_char_unescape(int c); +void grecs_line_acc_grow(const char *text, size_t len); +void grecs_line_acc_grow_unescape_last(char *text, size_t len); + +void grecs_line_begin(void); +#define grecs_line_add grecs_line_acc_grow +char *grecs_line_finish(void); + +int grecs_str_is_ipv4(const char *addr); +int grecs_str_is_num(const char *s); +int grecs_str_is_ipv6(const char *addr); +int grecs_str_is_num(const char *s); +int grecs_str_is_ipaddr(const char *addr); + +#endif diff --git a/include/grecs/list.h b/include/grecs/list.h new file mode 100644 index 0000000..efccd56 --- /dev/null +++ b/include/grecs/list.h @@ -0,0 +1,55 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_LIST_H +#define _GRECS_LIST_H + +typedef struct grecs_list_entry *grecs_list_entry_t; +typedef struct grecs_list *grecs_list_t; + +struct grecs_list_entry { + struct grecs_list_entry *next, *prev; + void *data; +}; + +struct grecs_list { + struct grecs_list_entry *head, *tail; + size_t count; + int (*cmp)(const void *, const void *); + void (*free_entry)(void *); +}; + +grecs_list_t grecs_list_create(void); +size_t grecs_list_size(grecs_list_t); +void grecs_list_append(grecs_list_t, void *); +void grecs_list_push(grecs_list_t, void *); +void *grecs_list_pop(grecs_list_t); +void *grecs_list_locate(grecs_list_t, void *); +void *grecs_list_index(grecs_list_t, size_t); +void *grecs_list_remove_tail(grecs_list_t); +void grecs_list_remove_entry(grecs_list_t, grecs_list_entry_t); +void grecs_list_clear(grecs_list_t); +void grecs_list_free(grecs_list_t); +void grecs_list_add(grecs_list_t, grecs_list_t); + +/* FIXME */ +struct grecs_list *_grecs_simple_list_create(int dispose); +struct grecs_list *grecs_value_list_create(void); + + + + +#endif diff --git a/include/grecs/locus.h b/include/grecs/locus.h new file mode 100644 index 0000000..4ca6d21 --- /dev/null +++ b/include/grecs/locus.h @@ -0,0 +1,80 @@ +/* grecs - Gray's Extensible Configuration System + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_LOCUS_H +#define _GRECS_LOCUS_H + +struct grecs_locus_point { + char *file; + unsigned line; + unsigned col; +}; + +#define grecs_locus_point_advance_line(loc) do { \ + (loc).line++; \ + (loc).col = 0; \ + } while (0) + +#define GRECS_LOCUS_POINT_EQ(a,b) \ + ((strcmp((a)->file, (b)->file) == 0) && ((a)->line == (b)->line)) + +typedef struct grecs_locus { + struct grecs_locus_point beg; + struct grecs_locus_point end; +} grecs_locus_t; + +#define YYLTYPE grecs_locus_t + +#define YYLLOC_DEFAULT(Current, Rhs, N) \ + do { \ + if (N) { \ + (Current).beg = YYRHSLOC(Rhs, 1).beg; \ + (Current).end = YYRHSLOC(Rhs, N).end; \ + } else { \ + (Current).beg = YYRHSLOC(Rhs, 0).end; \ + (Current).end = (Current).beg; \ + } \ + } while (0) + +#define YY_LOCATION_PRINT(File, Loc) do { \ + if ((Loc).beg.col == 0) \ + fprintf(File, "%s:%u", \ + (Loc).beg.file, \ + (Loc).beg.line); \ + else if (strcmp((Loc).beg.file, (Loc).end.file)) \ + fprintf(File, "%s:%u.%u-%s:%u.%u", \ + (Loc).beg.file, \ + (Loc).beg.line, (Loc).beg.col, \ + (Loc).end.file, \ + (Loc).end.line, (Loc).end.col); \ + else if ((Loc).beg.line != (Loc).end.line) \ + fprintf(File, "%s:%u.%u-%u.%u", \ + (Loc).beg.file, \ + (Loc).beg.line, (Loc).beg.col, \ + (Loc).end.line, (Loc).end.col); \ + else if ((Loc).beg.col != (Loc).end.col) \ + fprintf(File, "%s:%u.%u-%u", \ + (Loc).beg.file, \ + (Loc).beg.line, (Loc).beg.col, \ + (Loc).end.col); \ + else \ + fprintf(File, "%s:%u.%u", \ + (Loc).beg.file, \ + (Loc).beg.line, \ + (Loc).beg.col); \ + } while (0) + +#endif diff --git a/include/grecs/mem.h b/include/grecs/mem.h new file mode 100644 index 0000000..de46b32 --- /dev/null +++ b/include/grecs/mem.h @@ -0,0 +1,33 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_MEM_H +#define _GRECS_MEM_H + +extern void *(*grecs_malloc_fun)(size_t size); +extern void *(*grecs_realloc_fun)(void *ptr, size_t size); +extern void (*grecs_alloc_die_fun)(void); +extern void (*grecs_free_fun)(void *ptr); + +void *grecs_malloc(size_t size); +void *grecs_zalloc(size_t size); +void *grecs_calloc(size_t nmemb, size_t size); +void *grecs_realloc(void *ptr, size_t size); +void grecs_alloc_die(void); +char *grecs_strdup(const char *str); +void grecs_free(void *ptr); + +#endif diff --git a/include/grecs/node.h b/include/grecs/node.h new file mode 100644 index 0000000..5bbe9dc --- /dev/null +++ b/include/grecs/node.h @@ -0,0 +1,62 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_NODE_H +#define _GRECS_NODE_H + +#include +#include +#include + +enum grecs_node_type { + grecs_node_root, + grecs_node_stmt, + grecs_node_block +}; + +typedef struct grecs_node { + enum grecs_node_type type; + grecs_locus_t locus; + struct grecs_node *up; + struct grecs_node *down; + struct grecs_node *next; + struct grecs_node *prev; + char *ident; + grecs_locus_t idloc; + union { + grecs_value_t *value; + grecs_symtab_t texttab; + } v; +} grecs_node_t; + +void grecs_node_free(struct grecs_node *node); +struct grecs_node *grecs_node_create(enum grecs_node_type type, + grecs_locus_t *loc); +struct grecs_node *grecs_node_create_points(enum grecs_node_type type, + struct grecs_locus_point beg, + struct grecs_locus_point end); +void grecs_node_bind(struct grecs_node *master, struct grecs_node *node, + int dn); +int grecs_node_eq(struct grecs_node *a, struct grecs_node *b); +int grecs_node_unlink(struct grecs_node *node); + +struct grecs_node *grecs_node_from_path(const char *path, const char *value); +struct grecs_node *grecs_node_from_path_locus(const char *path, + const char *value, + grecs_locus_t *locus, + grecs_locus_t *vallocus); + +#endif diff --git a/include/grecs/opt.h b/include/grecs/opt.h new file mode 100644 index 0000000..5153033 --- /dev/null +++ b/include/grecs/opt.h @@ -0,0 +1,58 @@ +/* grecs - Gray's Extensible Configuration System + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_OPT_H +#define _GRECS_OPT_H + +struct grecs_proginfo { + const char *progname; + char **subcmd; + const char *docstring; + const char *args_doc; + struct grecs_opthelp *opthelp; + size_t optcount; + void (*print_help_hook)(FILE *stream); + void (*print_version_hook)(FILE *stream); + const char *package; + const char *version; + const char *license; + const char *copyright_year; + const char *copyright_holder; + const char **authors; + const char *bug_address; + const char *url; + const char *epilogue; +}; + +struct grecs_opthelp { + const char *opt; + const char *arg; + int is_optional; + const char *descr; +}; + +#define DESCRCOLUMN 30 +#define RMARGIN 79 +#define GROUPCOLUMN 2 +#define USAGECOLUMN 13 + +void grecs_print_help(struct grecs_proginfo *pinfo); +void grecs_print_usage(struct grecs_proginfo *pinfo); +void grecs_print_version_only(struct grecs_proginfo *pinfo, FILE *stream); +void grecs_print_version(struct grecs_proginfo *pinfo, FILE *stream); + +#endif + diff --git a/include/grecs/parser.h b/include/grecs/parser.h new file mode 100644 index 0000000..00878f4 --- /dev/null +++ b/include/grecs/parser.h @@ -0,0 +1,53 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_PARSER_H +#define _GRECS_PARSER_H + +typedef struct grecs_node *(*grecs_parser_t)(const char *name, int trace); + +#define GRECS_TRACE_GRAM 0x01 +#define GRECS_TRACE_LEX 0x02 + +extern int grecs_trace_flags; +extern grecs_parser_t grecs_parser_fun; +extern int grecs_default_port; + +extern struct grecs_locus_point grecs_current_locus_point; +extern grecs_locus_t grecs_locus; +extern int grecs_adjust_string_locations; +extern int grecs_error_count; + +/* Main entry point */ +struct grecs_node *grecs_parse(const char *name); +void grecs_gram_trace(int n); +void grecs_lex_trace(int n); + +/* Parsers: */ +struct grecs_node *grecs_grecs_parser(const char *name, int traceflags); +struct grecs_node *grecs_meta1_parser(const char *name, int traceflags); +struct grecs_node *grecs_bind_parser(const char *name, int traceflags); +struct grecs_node *grecs_dhcpd_parser(const char *name, int traceflags); +struct grecs_node *grecs_git_parser(const char *name, int traceflags); +struct grecs_node *grecs_path_parser(const char *name, int traceflags); + + +/* Parser database */ +int grecs_enumerate_parsers(int (*fun)(const char *, grecs_parser_t, void *), + void *); +grecs_parser_t grecs_get_parser_by_type(const char *type); + +#endif diff --git a/include/grecs/preproc.h b/include/grecs/preproc.h new file mode 100644 index 0000000..798e879 --- /dev/null +++ b/include/grecs/preproc.h @@ -0,0 +1,46 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_PREPROC_H +#define _GRECS_PREPROC_H + +#include + +extern const char *grecs_preprocessor; + +size_t grecs_preproc_fill_buffer(char *buf, size_t size); +void grecs_preproc_add_include_dir(char *dir); +int grecs_preproc_init(const char *name); +void grecs_preproc_done(void); +int grecs_preproc_run(const char *config_file, const char *extpp); + +#define GRECS_STD_INCLUDE 0x01 +#define GRECS_USR_INCLUDE 0x02 + +size_t grecs_include_path_count(int flag); +int grecs_foreach_include_dir(int flag, int (*fun)(int, const char *, void *), + void *data); + +char *grecs_find_include_file(const char *name, int allow_cwd); + +FILE *grecs_preproc_extrn_start(const char *file, pid_t *ppid); +void grecs_preproc_extrn_shutdown(pid_t pid); + +void grecs_include_path_clear(void); +void grecs_include_path_setup(const char *dir, ...); +void grecs_include_path_setup_v(char **dirs); + +#endif diff --git a/include/grecs/sockaddr.h b/include/grecs/sockaddr.h new file mode 100644 index 0000000..c8a3de2 --- /dev/null +++ b/include/grecs/sockaddr.h @@ -0,0 +1,66 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_SOCKADDR_H +#define _GRECS_SOCKADDR_H + +struct grecs_sockaddr { +#if GRECS_SOCKADDR_LIST + struct grecs_sockaddr *next; +#endif + int len; + struct sockaddr *sa; +}; + +#if GRECS_SOCKADDR_LIST + +#define GRECS_AH_PASSIVE 0x01 +#define GRECS_HINT_SERVICE 0x02 +#define GRECS_HINT_PORT 0x04 + +struct grecs_sockaddr_hints { + int flags; + char *service; + unsigned short port; +}; + +extern struct grecs_sockaddr_hints *grecs_sockaddr_hints; + +struct grecs_sockaddr *grecs_sockaddr_new(size_t s); +void grecs_sockaddr_free(struct grecs_sockaddr *p); + +int grecs_str_to_sockaddr(struct grecs_sockaddr **sap, + const char *arg, struct grecs_sockaddr_hints *gh, + grecs_locus_t const *locus); +#endif + +#define GRECS_INADDR_BYTES 16 + +struct grecs_cidr +{ + int family; + int len; + unsigned char address[GRECS_INADDR_BYTES]; + unsigned char netmask[GRECS_INADDR_BYTES]; +}; + +int grecs_str_to_cidr(struct grecs_cidr *pcidr, const char *str, + grecs_locus_t const *locus); + +int grecs_sockaddr_to_cidr(struct grecs_cidr *cidr, const struct sockaddr *sa); +int grecs_sockadd_cidr_match(struct sockaddr *sa, struct grecs_cidr *cidr); + +#endif diff --git a/include/grecs/symtab.h b/include/grecs/symtab.h new file mode 100644 index 0000000..a4a7106 --- /dev/null +++ b/include/grecs/symtab.h @@ -0,0 +1,52 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_SYMTAB_H +#define _GRECS_SYMTAB_H + +typedef struct grecs_symtab *grecs_symtab_t; + +struct grecs_syment { + char *name; +}; + +typedef int (*grecs_symtab_enumerator_t)(void *sym, void *data); + +const char *grecs_symtab_strerror(int rc); + +void *grecs_symtab_lookup_or_install(grecs_symtab_t st, + void *key, int *install); +void grecs_symtab_clear(grecs_symtab_t st); +grecs_symtab_t grecs_symtab_create(size_t elsize, + unsigned (*hash_fun)(void *, unsigned long), + int (*cmp_fun)(const void *, const void *), + int (*copy_fun)(void *, void *), + void *(*alloc_fun)(size_t), + void (*free_fun)(void *)); +grecs_symtab_t grecs_symtab_create_default(size_t elsize); + +void grecs_symtab_free(grecs_symtab_t pst); +int grecs_symtab_remove(grecs_symtab_t st, void *elt); +int grecs_symtab_replace(grecs_symtab_t st, void *ent, void **old_ent); +int grecs_symtab_enumerate(grecs_symtab_t st, + grecs_symtab_enumerator_t fun, void *data); + +size_t grecs_symtab_count_entries(grecs_symtab_t st); + +unsigned grecs_hash_string(const char *name, unsigned long hashsize); +unsigned grecs_hash_string_ci(const char *name, unsigned long hashsize); + +#endif diff --git a/include/grecs/table.h b/include/grecs/table.h new file mode 100644 index 0000000..4210c6f --- /dev/null +++ b/include/grecs/table.h @@ -0,0 +1,98 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_TABLE_H +#define _GRECS_TABLE_H + +#include + +enum grecs_data_type { + grecs_type_void, + grecs_type_string, + grecs_type_short, + grecs_type_ushort, + grecs_type_int, + grecs_type_uint, + grecs_type_long, + grecs_type_ulong, + grecs_type_size, +/* grecs_type_off,*/ + grecs_type_time, + grecs_type_bool, + grecs_type_ipv4, + grecs_type_cidr, + grecs_type_host, + grecs_type_sockaddr, + grecs_type_section, + grecs_type_null +}; + +#define GRECS_DFLT 0x00 +#define GRECS_AGGR 0x01 +#define GRECS_MULT 0x02 +#define GRECS_INAC 0x04 +#define GRECS_LIST 0x08 +#define GRECS_HIDDEN 0x10 + +enum grecs_callback_command { + grecs_callback_section_begin, + grecs_callback_section_end, + grecs_callback_set_value +}; + +typedef int (*grecs_callback_fn)( +#if GRECS_TREE_API + enum grecs_callback_command cmd, + grecs_node_t * /* node */, + void * /* varptr */, + void * /* cb_data */ +#else + enum grecs_callback_command cmd, + grecs_locus_t * /* locus */, + void * /* varptr */, + grecs_value_t * /* value */, + void * /* cb_data */ +#endif + ); + +struct grecs_keyword { + const char *ident; + const char *argname; + const char *docstring; + enum grecs_data_type type; + int flags; + void *varptr; + size_t offset; + grecs_callback_fn callback; + void *callback_data; + struct grecs_keyword *kwd; +}; + +extern int grecs_string_convert(void *target, enum grecs_data_type type, + const char *string, + grecs_locus_t const *locus); +extern void grecs_process_ident(struct grecs_keyword *kwp, + grecs_value_t *value, + void *base, + grecs_locus_t *locus); + +const char *grecs_data_type_string(enum grecs_data_type type); + +int grecs_tree_process(struct grecs_node *node, struct grecs_keyword *kwd); +int grecs_tree_reduce(struct grecs_node *node, struct grecs_keyword *kwd, + int flags); + +#endif diff --git a/include/grecs/tree.h b/include/grecs/tree.h new file mode 100644 index 0000000..2fb26dd --- /dev/null +++ b/include/grecs/tree.h @@ -0,0 +1,71 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_TREE_H +#define _GRECS_TREE_H + +#include + +int grecs_tree_free(struct grecs_node *node); +void grecs_tree_sort(struct grecs_node *node, + int (*compare)(struct grecs_node const *, + struct grecs_node const *)); +struct grecs_node *grecs_tree_first_node(struct grecs_node *tree); +struct grecs_node *grecs_next_node(struct grecs_node *node); + +struct grecs_node *grecs_find_node(struct grecs_node *node, const char *path); + +enum grecs_tree_recurse_op { + grecs_tree_recurse_set, + grecs_tree_recurse_pre, + grecs_tree_recurse_post +}; + +enum grecs_tree_recurse_res { + grecs_tree_recurse_ok, + grecs_tree_recurse_fail, + grecs_tree_recurse_skip, + grecs_tree_recurse_stop +}; + +typedef enum grecs_tree_recurse_res + (*grecs_tree_recursor_t)(enum grecs_tree_recurse_op, + struct grecs_node *, void *); + +int grecs_tree_recurse(struct grecs_node *node, grecs_tree_recursor_t recfun, + void *data); +int grecs_tree_join(struct grecs_node *dst, struct grecs_node *src); + +enum grecs_tree_recurse_res grecs_node_exact_match( + enum grecs_tree_recurse_op op, + struct grecs_node *node, void *data); + +typedef struct grecs_match_buf *grecs_match_buf_t; +struct grecs_node *grecs_match_first(struct grecs_node *tree, + const char *pattern, + grecs_match_buf_t *buf); +struct grecs_node *grecs_match_next(struct grecs_match_buf *buf); +void grecs_match_buf_free(struct grecs_match_buf *buf); +grecs_match_buf_t grecs_match_buf_create(int argc, char **argv, + struct grecs_value **labelv); +struct grecs_node *grecs_match_buf_first(struct grecs_match_buf *buf, + struct grecs_node *tree); +struct grecs_node *grecs_match_buf_get_node(grecs_match_buf_t buf); +size_t grecs_match_buf_get_args(grecs_match_buf_t buf, char ***argv); +struct grecs_node *grecs_match_buf_get_root(grecs_match_buf_t buf); +void grecs_match_buf_set_root(grecs_match_buf_t buf, struct grecs_node *root); + +#endif diff --git a/include/grecs/txtacc.h b/include/grecs/txtacc.h new file mode 100644 index 0000000..d6dc1c4 --- /dev/null +++ b/include/grecs/txtacc.h @@ -0,0 +1,36 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_TXTACC_H +#define _GRECS_TXTACC_H + +#define GRECS_TXTACC_BUFSIZE 1024 +typedef struct grecs_txtacc *grecs_txtacc_t; + +grecs_txtacc_t grecs_txtacc_create(void); +void grecs_txtacc_free(grecs_txtacc_t); +void grecs_txtacc_grow(grecs_txtacc_t, const char *, size_t); +void grecs_txtacc_grow_string(grecs_txtacc_t, const char *); +void grecs_txtacc_grow_string_escape(grecs_txtacc_t, const char *); +#define grecs_txtacc_grow_char(acc,c) \ + do { \ + char __ch = c; \ + grecs_txtacc_grow(acc,&__ch,1); \ + } while (0) +char *grecs_txtacc_finish(grecs_txtacc_t, int); +void grecs_txtacc_free_string(grecs_txtacc_t, char *); + +#endif diff --git a/include/grecs/types.h.in b/include/grecs/types.h.in new file mode 100644 index 0000000..b891a05 --- /dev/null +++ b/include/grecs/types.h.in @@ -0,0 +1,24 @@ +#ifndef _GRECS_TYPES_H +#define _GRECS_TYPES_H + +#define GRECS_VERSION_MAJOR 1 +#define GRECS_VERSION_MINOR 0 + +#define GRECS_TREE_API @GRECS_TREE_API@ +#define GRECS_SOCKADDR_LIST @GRECS_SOCKADDR_LIST@ + +#if ENABLE_NLS +# include "gettext.h" +#else +# ifndef gettext +# define gettext(msgid) msgid +# endif +#endif +#ifndef _ +# define _(msgid) gettext(msgid) +#endif +#ifndef N_ +# define N_(s) s +#endif + +#endif diff --git a/include/grecs/util.h b/include/grecs/util.h new file mode 100644 index 0000000..cf3bee1 --- /dev/null +++ b/include/grecs/util.h @@ -0,0 +1,26 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_UTIL_H +#define _GRECS_UTIL_H + +#include + +ssize_t grecs_getline(char **pbuf, size_t *psize, FILE *fp); +int grecs_vasprintf(char **pbuf, size_t *psize, const char *fmt, va_list ap); +int grecs_asprintf(char **pbuf, size_t *psize, const char *fmt, ...); + +#endif diff --git a/include/grecs/value.h b/include/grecs/value.h new file mode 100644 index 0000000..73f979c --- /dev/null +++ b/include/grecs/value.h @@ -0,0 +1,52 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_VALUE_H +#define _GRECS_VALUE_H + +#include +#include + +#define GRECS_TYPE_STRING 0 +#define GRECS_TYPE_LIST 1 +#define GRECS_TYPE_ARRAY 2 + +typedef struct grecs_value { + int type; + grecs_locus_t locus; + union { + grecs_list_t list; + char *string; + struct { + size_t c; + struct grecs_value **v; + } arg; + } v; +} grecs_value_t; + +#define GRECS_VALUE_EMPTY_P(val) \ + (!(val) || \ + ((val)->type == GRECS_TYPE_STRING && (val)->v.string == NULL)) + +void grecs_value_free(struct grecs_value *val); +void grecs_value_free_content(struct grecs_value *val); +grecs_value_t *grecs_value_ptr_from_static(grecs_value_t *input); + +int grecs_value_eq(struct grecs_value *a, struct grecs_value *b); +int grecs_value_match(struct grecs_value *pat, struct grecs_value *b, + int flags); + +#endif diff --git a/include/grecs/version.h b/include/grecs/version.h new file mode 100644 index 0000000..f37adc6 --- /dev/null +++ b/include/grecs/version.h @@ -0,0 +1,40 @@ +/* grecs - Gray's Extensible Configuration System -*- c -*- + Copyright (C) 2007-2016 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 . */ + +#ifndef _GRECS_VERSION_H +#define _GRECS_VERSION_H + +struct grecs_version_info { + const char *package; + const char *version; + const char *id; + int major; + int minor; + int patch; + char *suffix; + char *buffer; +}; + +struct grecs_version_info *grecs_version(void); +int grecs_version_cmp(const char *, const char *, int *); +int grecs_version_ok(const char *); +void grecs_version_info_free(struct grecs_version_info *); +struct grecs_version_info *grecs_version_split(const char *); +int grecs_version_info_cmp(struct grecs_version_info *, + struct grecs_version_info *, + int *); + +#endif diff --git a/include/wordsplit.h b/include/wordsplit.h new file mode 100644 index 0000000..a7f6dd5 --- /dev/null +++ b/include/wordsplit.h @@ -0,0 +1,250 @@ +/* wordsplit - a word splitter + Copyright (C) 2009-2016 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 . */ + +#ifndef __WORDSPLIT_H +#define __WORDSPLIT_H + +#include + +typedef struct wordsplit wordsplit_t; + +/* Structure used to direct the splitting. Members marked with [Input] + can be defined before calling wordsplit(), those marked with [Output] + provide return values when the function returns. If neither mark is + used, the member is internal and must not be used by the caller. + + In the comments below, the + identifiers in parentheses indicate bits that must be set (or unset, if + starting with !) in the ws_flags to initialize or use the given member. + If not redefined explicitly, most of them are set to some reasonable + default value upon entry to wordsplit(). */ +struct wordsplit +{ + size_t ws_wordc; /* [Output] Number of words in ws_wordv. */ + char **ws_wordv; /* [Output] Array of parsed out words. */ + size_t ws_offs; /* [Input] (WRDSF_DOOFFS) Number of initial + elements in ws_wordv to fill with NULLs. */ + size_t ws_wordn; /* Number of elements ws_wordv can accomodate. */ + int ws_flags; /* [Input] Flags passed to wordsplit. */ + int ws_options; /* [Input] (WRDSF_PATHEXPAND) + Additional options. */ + const char *ws_delim; /* [Input] (WRDSF_DELIM) Word delimiters. */ + const char *ws_comment; /* [Input] (WRDSF_COMMENT) Comment characters. */ + const char *ws_escape[2]; /* [Input] (WRDSF_ESCAPE) Characters to be escaped + with backslash. */ + void (*ws_alloc_die) (wordsplit_t *wsp); + /* [Input] (WRDSF_ALLOC_DIE) Function called when + out of memory. Must not return. */ + void (*ws_error) (const char *, ...) + __attribute__ ((__format__ (__printf__, 1, 2))); + /* [Input] (WRDSF_ERROR) Function used for error + reporting */ + void (*ws_debug) (const char *, ...) + __attribute__ ((__format__ (__printf__, 1, 2))); + /* [Input] (WRDSF_DEBUG) Function used for debug + output. */ + const char **ws_env; /* [Input] (WRDSF_ENV, !WRDSF_NOVAR) Array of + environment variables. */ + + char **ws_envbuf; + size_t ws_envidx; + size_t ws_envsiz; + + int (*ws_getvar) (char **ret, const char *var, size_t len, void *clos); + /* [Input] (WRDSF_GETVAR, !WRDSF_NOVAR) Looks up + the name VAR (LEN bytes long) in the table of + variables and if found returns in memory + location pointed to by RET the value of that + variable. Returns WRDSE_OK (0) on success, + and an error code (see WRDSE_* defines below) + on error. User-specific errors can be returned + by storing the error diagnostic string in RET + and returning WRDSE_USERERR. + Whatever is stored in RET, it must be allocated + using malloc(3). */ + void *ws_closure; /* [Input] (WRDSF_CLOSURE) Passed as the CLOS + argument to ws_getvar and ws_command. */ + int (*ws_command) (char **ret, const char *cmd, size_t len, char **argv, + void *clos); + /* [Input] (!WRDSF_NOCMD) Returns in the memory + location pointed to by RET the expansion of + the command CMD (LEN bytes nong). If WRDSF_ARGV + flag is set, ARGV contains CMD split out to + words. Otherwise ARGV is NULL. + + See ws_getvar for a discussion of possible + return values. */ + + const char *ws_input; /* Input string (the S argument to wordsplit. */ + size_t ws_len; /* Length of ws_input. */ + size_t ws_endp; /* Points past the last processed byte in + ws_input. */ + int ws_errno; /* [Output] Error code, if an error occurred. */ + char *ws_usererr; /* Points to textual description of + the error, if ws_errno is WRDSE_USERERR. Must + be allocated with malloc(3). */ + struct wordsplit_node *ws_head, *ws_tail; + /* Doubly-linked list of parsed out nodes. */ + int ws_lvl; /* Invocation nesting level. */ +}; + +/* Initial size for ws_env, if allocated automatically */ +#define WORDSPLIT_ENV_INIT 16 + +/* Wordsplit flags. */ +/* Append the words found to the array resulting from a previous + call. */ +#define WRDSF_APPEND 0x00000001 +/* Insert ws_offs initial NULLs in the array ws_wordv. + (These are not counted in the returned ws_wordc.) */ +#define WRDSF_DOOFFS 0x00000002 +/* Don't do command substitution. */ +#define WRDSF_NOCMD 0x00000004 +/* The parameter p resulted from a previous call to + wordsplit(), and wordsplit_free() was not called. Reuse the + allocated storage. */ +#define WRDSF_REUSE 0x00000008 +/* Print errors */ +#define WRDSF_SHOWERR 0x00000010 +/* Consider it an error if an undefined variable is expanded. */ +#define WRDSF_UNDEF 0x00000020 +/* Don't do variable expansion. */ +#define WRDSF_NOVAR 0x00000040 +/* Abort on ENOMEM error */ +#define WRDSF_ENOMEMABRT 0x00000080 +/* Trim off any leading and trailind whitespace */ +#define WRDSF_WS 0x00000100 +/* Handle single quotes */ +#define WRDSF_SQUOTE 0x00000200 +/* Handle double quotes */ +#define WRDSF_DQUOTE 0x00000400 +/* Handle single and double quotes */ +#define WRDSF_QUOTE (WRDSF_SQUOTE|WRDSF_DQUOTE) +/* Replace each input sequence of repeated delimiters with a single + delimiter */ +#define WRDSF_SQUEEZE_DELIMS 0x00000800 +/* Return delimiters */ +#define WRDSF_RETURN_DELIMS 0x00001000 +/* Treat sed expressions as words */ +#define WRDSF_SED_EXPR 0x00002000 +/* ws_delim field is initialized */ +#define WRDSF_DELIM 0x00004000 +/* ws_comment field is initialized */ +#define WRDSF_COMMENT 0x00008000 +/* ws_alloc_die field is initialized */ +#define WRDSF_ALLOC_DIE 0x00010000 +/* ws_error field is initialized */ +#define WRDSF_ERROR 0x00020000 +/* ws_debug field is initialized */ +#define WRDSF_DEBUG 0x00040000 +/* ws_env field is initialized */ +#define WRDSF_ENV 0x00080000 +/* ws_getvar field is initialized */ +#define WRDSF_GETVAR 0x00100000 +/* enable debugging */ +#define WRDSF_SHOWDBG 0x00200000 +/* Don't split input into words. Useful for side effects. */ +#define WRDSF_NOSPLIT 0x00400000 +/* Keep undefined variables in place, instead of expanding them to + empty strings. */ +#define WRDSF_KEEPUNDEF 0x00800000 +/* Warn about undefined variables */ +#define WRDSF_WARNUNDEF 0x01000000 +/* Handle C escapes */ +#define WRDSF_CESCAPES 0x02000000 +/* ws_closure is set */ +#define WRDSF_CLOSURE 0x04000000 +/* ws_env is a Key/Value environment, i.e. the value of a variable is + stored in the element that follows its name. */ +#define WRDSF_ENV_KV 0x08000000 +/* ws_escape is set */ +#define WRDSF_ESCAPE 0x10000000 +/* Incremental mode */ +#define WRDSF_INCREMENTAL 0x20000000 +/* Perform pathname and tilde expansion */ +#define WRDSF_PATHEXPAND 0x40000000 +/* ws_options is initialized */ +#define WRDSF_OPTIONS 0x80000000 + +#define WRDSF_DEFFLAGS \ + (WRDSF_NOVAR | WRDSF_NOCMD | \ + WRDSF_QUOTE | WRDSF_SQUEEZE_DELIMS | WRDSF_CESCAPES) + +/* Remove the word that produces empty string after path expansion */ +#define WRDSO_NULLGLOB 0x00000001 +/* Print error message if path expansion produces empty string */ +#define WRDSO_FAILGLOB 0x00000002 +/* Allow a leading period to be matched by metacharacters. */ +#define WRDSO_DOTGLOB 0x00000004 +/* ws_command needs argv parameter */ +#define WRDSO_ARGV 0x00000008 +/* Keep backslash in unrecognized escape sequences in words */ +#define WRDSO_BSKEEP_WORD 0x00000010 +/* Handle octal escapes in words */ +#define WRDSO_OESC_WORD 0x00000020 +/* Handle hex escapes in words */ +#define WRDSO_XESC_WORD 0x00000040 + +/* Keep backslash in unrecognized escape sequences in quoted strings */ +#define WRDSO_BSKEEP_QUOTE 0x00000100 +/* Handle octal escapes in quoted strings */ +#define WRDSO_OESC_QUOTE 0x00000200 +/* Handle hex escapes in quoted strings */ +#define WRDSO_XESC_QUOTE 0x00000400 + +#define WRDSO_BSKEEP WRDSO_BSKEEP_WORD +#define WRDSO_OESC WRDSO_OESC_WORD +#define WRDSO_XESC WRDSO_XESC_WORD + +/* Indices into ws_escape */ +#define WRDSX_WORD 0 +#define WRDSX_QUOTE 1 + +/* Set escape option F in WS for words (Q==0) or quoted strings (Q==1) */ +#define WRDSO_ESC_SET(ws,q,f) ((ws)->ws_options |= ((f) << 4*(q))) +/* Test WS for escape option F for words (Q==0) or quoted strings (Q==1) */ +#define WRDSO_ESC_TEST(ws,q,f) ((ws)->ws_options & ((f) << 4*(q))) + +#define WRDSE_OK 0 +#define WRDSE_EOF WRDSE_OK +#define WRDSE_QUOTE 1 +#define WRDSE_NOSPACE 2 +#define WRDSE_USAGE 3 +#define WRDSE_CBRACE 4 +#define WRDSE_UNDEF 5 +#define WRDSE_NOINPUT 6 +#define WRDSE_PAREN 7 +#define WRDSE_GLOBERR 8 +#define WRDSE_USERERR 9 + +int wordsplit (const char *s, wordsplit_t *ws, int flags); +int wordsplit_len (const char *s, size_t len, wordsplit_t *ws, int flags); +void wordsplit_free (wordsplit_t *ws); +void wordsplit_free_words (wordsplit_t *ws); +void wordsplit_free_envbuf (wordsplit_t *ws); +void wordsplit_getwords (wordsplit_t *ws, size_t *wordc, char ***wordv); + +int wordsplit_c_unquote_char (int c); +int wordsplit_c_quote_char (int c); +size_t wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote); +void wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex); + +void wordsplit_perror (wordsplit_t *ws); +const char *wordsplit_strerror (wordsplit_t *ws); + +void wordsplit_clearerr (wordsplit_t *ws); + +#endif diff --git a/src/Make-inst.am b/src/Make-inst.am index 9dac1ad..a4b6aea 100644 --- a/src/Make-inst.am +++ b/src/Make-inst.am @@ -17,6 +17,5 @@ include Make.am lib_LTLIBRARIES=libgrecs.la libgrecs_la_SOURCES = $(GRECS_SRC) -include_HEADERS = $(GRECS_HDR) m4datadir = $(datadir)/aclocal dist_m4data_DATA = libgrecs.m4 diff --git a/src/Make-shared.am b/src/Make-shared.am index 8ec4a76..9a762a4 100644 --- a/src/Make-shared.am +++ b/src/Make-shared.am @@ -17,9 +17,3 @@ include Make.am noinst_LTLIBRARIES=libgrecs.la libgrecs_la_SOURCES = $(GRECS_SRC) -if GRECS_COND_INSTALLHEADERS - grecsincludedir = @GRECS_INCLUDE_DIR@ - grecsinclude_HEADERS = $(GRECS_HDR) -else - noinst_HEADERS += $(GRECS_HDR) -endif diff --git a/src/Make-static.am b/src/Make-static.am index 7532562..26