/* grecs - Gray's Extensible Configuration System
Copyright (C) 2007-2011 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
#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
struct grecs_version_info {
const char *package;
const char *version;
int major;
int minor;
int patch;
char *suffix;
};
typedef struct {
char *file;
int line;
} grecs_locus_t;
extern grecs_locus_t grecs_locus;
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
};
#define GRECS_AGGR 0x1000
#define GRECS_LIST 0x8000
#define GRECS_TYPE_MASK 0x00ff
#define GRECS_TYPE(c) ((c) & GRECS_TYPE_MASK)
#define GRECS_IS_LIST(c) ((c) & GRECS_LIST)
enum grecs_callback_command {
grecs_callback_section_begin,
grecs_callback_section_end,
grecs_callback_set_value
};
#define GRECS_TYPE_STRING 0
#define GRECS_TYPE_LIST 1
#define GRECS_TYPE_ARRAY 2
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 *);
};
typedef struct grecs_value {
int type;
union {
struct grecs_list *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))
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;
union {
struct grecs_value *value;
struct grecs_symtab *texttab;
} v;
} grecs_node_t;
typedef int (*grecs_callback_fn)(
enum grecs_callback_command cmd,
grecs_locus_t * /* locus */,
void * /* varptr */,
grecs_value_t * /* value */,
void * /* cb_data */
);
struct grecs_keyword {
const char *ident;
const char *argname;
const char *docstring;
enum grecs_data_type type;
void *varptr;
size_t offset;
grecs_callback_fn callback;
void *callback_data;
struct grecs_keyword *kwd;
};
struct grecs_sockaddr {
int len;
struct sockaddr *sa;
};
void grecs_version(struct grecs_version_info *pv);
int grecs_version_cmp(const char *vstr);
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);
grecs_value_t *grecs_value_ptr_from_static(grecs_value_t *input);
extern void (*grecs_print_diag_fun)(grecs_locus_t *, int, int, const char*);
void grecs_warning(grecs_locus_t *locus, int errcode, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
void grecs_error(grecs_locus_t *locus, int errcode, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
void grecs_gram_trace(int n);
void grecs_lex_trace(int n);
int grecs_lex_begin(const char*);
void grecs_lex_end(int err);
struct grecs_node *grecs_parse(const char *name);
struct grecs_list *_grecs_simple_list_create(int dispose);
struct grecs_list *grecs_value_list_create(void);
void grecs_line_begin(void);
void grecs_line_add(const char *text, size_t len);
char *grecs_line_finish(void);
extern int grecs_string_convert(void *target, enum grecs_data_type type,
const char *string, grecs_locus_t *locus);
extern void grecs_process_ident(struct grecs_keyword *kwp,
grecs_value_t *value,
void *base,
grecs_locus_t *locus);
struct grecs_node *grecs_node_create(enum grecs_node_type type,
grecs_locus_t *loc);
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);
extern grecs_locus_t grecs_current_locus;
extern int grecs_error_count;
extern int grecs_default_port;
extern const char *grecs_preprocessor;
extern int grecs_log_to_stderr;
extern void (*grecs_log_setup_hook)();
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);
FILE *grecs_preproc_extrn_start(const char *file, pid_t *ppid);
void grecs_preproc_extrn_shutdown(pid_t pid);
char *grecs_install_text(const char *str);
void grecs_destroy_text(void);
struct grecs_symtab *grecs_text_table(void);
void grecs_include_path_setup(const char *dir, ...);
void grecs_include_path_setup_v(char **dirs);
const char *grecs_data_type_string(enum grecs_data_type type);
void grecs_format_docstring(const char *docstring, unsigned level,
FILE *stream);
void grecs_format_simple_statement(struct grecs_keyword *kwp,
unsigned level, FILE *stream);
void grecs_format_block_statement(struct grecs_keyword *kwp,
unsigned level, FILE *stream);
void grecs_format_statement_array(struct grecs_keyword *kwp,
unsigned n,
unsigned level, FILE *stream);
void grecs_format_locus(grecs_locus_t *locus, FILE *fp);
void grecs_format_node_path(struct grecs_node *node, int flag, FILE *fp);
void grecs_format_value(struct grecs_value *val, int flags, FILE *fp);
#define GRECS_NODE_FLAG_LOCUS 0x0100
#define GRECS_NODE_FLAG_PATH 0x0200
#define GRECS_NODE_FLAG_VALUE 0x0400
#define GRECS_NODE_FLAG_QUOTE 0x0800
#define GRECS_NODE_FLAG_NOQUOTE 0x1000
#define GRECS_NODE_FLAG_QUOTE_HEX 0x2000
#define GRECS_NODE_FLAG_DEFAULT \
(GRECS_NODE_FLAG_PATH|GRECS_NODE_FLAG_VALUE|GRECS_NODE_FLAG_QUOTE)
void grecs_format_node(struct grecs_node *node, int flags, FILE *fp);
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);
void grecs_list_clear(struct grecs_list *lp);
void grecs_list_free(struct grecs_list *lp);
void grecs_list_add(struct grecs_list *dst, struct grecs_list *src);
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, ...);
struct grecs_symtab;
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(struct grecs_symtab *st,
void *key, int *install);
void grecs_symtab_clear(struct grecs_symtab *st);
struct grecs_symtab *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 *));
struct grecs_symtab *grecs_symtab_create_default(size_t elsize);
void grecs_symtab_free(struct grecs_symtab *pst);
int grecs_symtab_remove(struct grecs_symtab *st, void *elt);
int grecs_symtab_replace(struct grecs_symtab *st, void *ent, void **old_ent);
int grecs_symtab_enumerate(struct grecs_symtab *st,
grecs_symtab_enumerator_t fun, void *data);
size_t grecs_symtab_count_entries(struct grecs_symtab *st);
void grecs_value_free(struct grecs_value *val);
void grecs_node_free(struct grecs_node *node);
int grecs_tree_free(struct grecs_node *node);
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);
int grecs_tree_process(struct grecs_node *node, struct grecs_keyword *kwd);
int grecs_value_eq(struct grecs_value *a, struct grecs_value *b);
struct grecs_node *grecs_find_node(struct grecs_node *node, const char *path);
struct grecs_node *grecs_node_from_path(const char *path, const char *value);
int grecs_tree_reduce(struct grecs_node *node, struct grecs_keyword *kwd,
int flags);
void grecs_tree_sort(struct grecs_node *node,
int (*compare)(struct grecs_node const *,
struct grecs_node const *));
#endif