summaryrefslogtreecommitdiffabout
path: root/tests/gcfset.c
Side-by-side diff
Diffstat (limited to 'tests/gcfset.c') (more/less context) (ignore whitespace changes)
-rw-r--r--tests/gcfset.c240
1 files changed, 240 insertions, 0 deletions
diff --git a/tests/gcfset.c b/tests/gcfset.c
new file mode 100644
index 0000000..d2264e3
--- a/dev/null
+++ b/tests/gcfset.c
@@ -0,0 +1,240 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include "grecs.h"
+
+struct logging_setup {
+ int use_syslog;
+ int print_priority;
+ char *tag;
+ char *facility;
+};
+
+struct logging_setup logging_setup;
+char *scalar_string;
+char *mailbox_pattern;
+char *mailbox_type;
+struct grecs_list *listvar;
+
+struct program {
+ char *name;
+ struct logging_setup logging_setup;
+ char *scalar_string;
+ grecs_locus_t locus;
+ struct program *next;
+};
+
+struct grecs_list *proglist;
+
+static int
+cb_logging_facility(enum grecs_callback_command cmd,
+ grecs_locus_t *locus,
+ void *varptr,
+ grecs_value_t *value,
+ void *cb_data)
+{
+ if (cmd != grecs_callback_set_value) {
+ grecs_error(locus, 0, _("Unexpected block statement"));
+ return 1;
+ }
+ if (!value || value->type != GRECS_TYPE_STRING) {
+ grecs_error(locus, 0, _("expected string argument"));
+ return 1;
+ }
+
+ *(char**)varptr = grecs_strdup(value->v.string);
+ return 0;
+}
+
+static struct grecs_keyword logging_kwtab[] = {
+ { "syslog", NULL, "Send to syslog",
+ grecs_type_bool, NULL,
+ offsetof(struct logging_setup, use_syslog) },
+ { "facility", "name", "Set logging facility",
+ grecs_type_string, NULL,
+ offsetof(struct logging_setup, facility), cb_logging_facility },
+ { "tag", "label", "Tag logging messages with this string",
+ grecs_type_string, NULL,
+ offsetof(struct logging_setup, tag) },
+ { "print-priority", NULL, "Prefix each message with its priority",
+ grecs_type_bool, NULL,
+ offsetof(struct logging_setup, print_priority) },
+ { NULL },
+};
+
+static struct grecs_keyword mailbox_kwtab[] = {
+ { "mailbox-pattern", NULL, "Default mailbox pattern",
+ grecs_type_string, &mailbox_pattern },
+ { "mailbox-type", NULL, "Default mailbox type",
+ grecs_type_string, &mailbox_type },
+ { NULL },
+};
+
+
+static struct grecs_keyword program_kwtab[] = {
+ { "scalar", "label", "Scalar string",
+ grecs_type_string, NULL, offsetof(struct program,scalar_string) },
+ { "logging", NULL, N_("Configure logging logging"),
+ grecs_type_section, NULL, offsetof(struct program,logging_setup),
+ NULL, NULL, logging_kwtab },
+ { NULL }
+};
+
+static int
+cb_program(enum grecs_callback_command cmd,
+ grecs_locus_t *locus,
+ void *varptr,
+ grecs_value_t *value,
+ void *cb_data)
+{
+ struct program *prog;
+ void **pdata = cb_data;
+
+ switch (cmd) {
+ case grecs_callback_section_begin:
+ if (!value || value->type != GRECS_TYPE_STRING) {
+ grecs_error(locus, 0, _("tag must be a string"));
+ return 0;
+ }
+ prog = grecs_zalloc(sizeof(*prog));
+ prog->name = grecs_strdup(value->v.string);
+ prog->locus = *locus;
+ *pdata = prog;
+ break;
+
+ case grecs_callback_section_end:
+ prog = *pdata;
+ if (!proglist)
+ proglist = grecs_list_create();
+ grecs_list_append(proglist, prog);
+ break;
+
+ case grecs_callback_set_value:
+ grecs_error(locus, 0, _("invalid use of block statement"));
+ }
+ return 0;
+}
+
+static struct grecs_keyword main_kwtab[] = {
+ { "scalar", "label", "Scalar string",
+ grecs_type_string, &scalar_string },
+ { "logging", NULL, N_("Configure logging logging"),
+ grecs_type_section, &logging_setup, 0, NULL,
+ NULL, logging_kwtab },
+ { "mailbox", NULL, N_("Mailbox configuration"),
+ grecs_type_section, NULL, 0, NULL, NULL, mailbox_kwtab },
+ { "program", "name: string", "Subprogram configuration",
+ grecs_type_section, NULL, 0, cb_program, NULL, program_kwtab },
+ { "listvar", NULL, "list variable",
+ grecs_type_string|GRECS_LIST, &listvar },
+ { NULL }
+};
+
+
+#define S(s) ((s) ? (s) : "(null)")
+
+static void
+print_logging_setup(struct logging_setup *p)
+{
+ printf("logging: %d/%s/%s/%d\n",
+ p->use_syslog, S(p->facility), S(p->tag), p->print_priority);
+}
+
+static void
+print_program(struct program *prog)
+{
+ printf("Program %s:\n", prog->name);
+ printf("scalar = %s\n", S(prog->scalar_string));
+ print_logging_setup(&prog->logging_setup);
+}
+
+
+static void
+usage(const char *arg, FILE *fp, int code)
+{
+ fprintf(fp, "usage: %s [-h] [-cfhelp] file\n", arg);
+ exit(code);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *progname = argv[0];
+ const char *file = NULL;
+ struct grecs_node *tree;
+ int cfhelp = 0;
+
+ while (--argc) {
+ char *arg = *++argv;
+ if (strcmp(arg, "-cfhelp") == 0)
+ cfhelp = 1;
+ else if (strcmp(arg, "-h") == 0)
+ usage(progname, stdout, 0);
+ else if (arg[0] == '-')
+ usage(progname, stderr, 1);
+ else if (file)
+ usage(progname, stderr, 1);
+ else
+ file = arg;
+ }
+
+ if ((!file && !cfhelp) || argc)
+ usage(progname, stderr, 1);
+
+ if (cfhelp) {
+ static char docstring[] =
+ "Sample configuration file structure.\n";
+ grecs_format_docstring(docstring, 0, stdout);
+ grecs_format_statement_array(main_kwtab, 1, 0, stdout);
+ exit(0);
+ }
+
+ tree = grecs_parse(file);
+ if (!tree)
+ exit(2);
+
+ if (grecs_tree_process(tree, main_kwtab))
+ exit(2);
+
+ printf("Global settings:\n");
+ printf("scalar = %s\n", S(scalar_string));
+ if (listvar) {
+ struct grecs_list_entry *ep;
+ printf("listvar =");
+ for (ep = listvar->head; ep; ep = ep->next)
+ printf(" \"%s\"", (char*)ep->data);
+ putchar('\n');
+ }
+
+ print_logging_setup(&logging_setup);
+
+ if (proglist) {
+ struct grecs_list_entry *ep;
+
+ printf("Programs configured: %d\n", grecs_list_size(proglist));
+ for (ep = proglist->head; ep; ep = ep->next)
+ print_program(ep->data);
+ }
+
+ exit(0);
+}
+

Return to:

Send suggestions and report system problems to the System administrator.