/* * Copyright (c) 2004 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: tree.c,v 1.6 2004/09/01 18:30:03 ca Exp $") #if SM_LIBCONF_ALONE #include #include #include #include "sm-conf.h" #else /* SM_LIBCONF_ALONE */ #include "sm/string.h" #include "sm/sm-conf.h" #include #endif /* SM_LIBCONF_ALONE */ /* TREE.C -- tree reader/dumper testbed. */ static int Verbose = 0; static int Noquotes = 0; static int Equations = 0; static void dump_entry(sm_conf_T *stream, sm_conf_node_T *node, int indent) { char const *name, *kw; size_t name_n, kw_n; sm_conf_node_T *sub; switch (sm_conf_node_type(stream, node)) { case SM_CONF_NODE_VALUE: if (Verbose > 1) fprintf(stderr, "value:\t"); if (sm_conf_value(stream, node, &name, &name_n)) { fprintf(stderr, "%p: can't get node value!\n", (void *)node); exit(1); } if (Noquotes) printf("%.*s", (int)name_n, name); else printf("\"%.*s\"", (int)name_n, name); break; case SM_CONF_NODE_LIST: if (Verbose > 1) fprintf(stderr, "list:\t"); switch (sm_conf_list_n(stream, node)) { case 0: printf("{}"); break; case 1: printf("{ "); dump_entry(stream, sm_conf_list_next(stream, node, NULL), indent + 2); printf(" }"); break; default: printf("{\n"); sub = NULL; while ((sub = sm_conf_list_next(stream, node, sub)) != NULL) { printf("%*s", indent + 2, ""); dump_entry(stream, sub, indent + 2); printf(",\n"); } printf("%*s}", indent, ""); break; } break; case SM_CONF_NODE_SECTION: if (Verbose > 1) fprintf(stderr, "section:\t"); if ( sm_conf_section_name(stream, node, &name, &name_n) || sm_conf_section_keyword(stream, node, &kw, &kw_n)) { fprintf(stderr, "%p: can't get section name?\n", (void*)node); return; } if (Equations) { if (kw != NULL) printf("section=%.*s\n", (int)kw_n, kw); if (name != NULL) printf("title=\"%.*s\"\n", (int)name_n, name); } else { if (kw != NULL) printf("%.*s ", (int)kw_n, kw); if (name != NULL) printf("\"%.*s\" ", (int)name_n, name); } putchar('{'); putchar('\n'); sub = NULL; while ((sub = sm_conf_section_next(stream, node, &name, &name_n, sub)) != NULL) { printf("%*s", indent + 2, ""); if (name != NULL) printf("%.*s = ", (int)name_n, name); dump_entry(stream, sub, indent + 2); printf(";\n"); } printf("%*s}", indent, ""); break; } } static void dump_root(sm_conf_T *stream, sm_conf_node_T *node) { char const *name; size_t name_n; sm_conf_node_T *sub; sub = NULL; while ((sub = sm_conf_section_next(stream, node, &name, &name_n, sub)) != NULL) { if (name != NULL) printf("%.*s = ", (int)name_n, name); dump_entry(stream, sub, 0); printf(";\n"); } } static int process(char const *name, FILE *fp) { sm_conf_T *stream; sm_conf_node_T *node; int err; if (((stream = sm_conf_new(name ? name : "*stdin*"))) == NULL) { fprintf(stderr, "error -- sm_conf_new() returns NULL!\n"); return 1; } if ((err = sm_conf_read_FILE(stream, name, fp)) != 0) { char buf[SM_CONF_ERROR_BUFFER_SIZE]; char const *e = NULL; fprintf(stderr, "%s: %s\n", name ? name : "*stdin*", sm_conf_strerror(err, buf, sizeof buf)); while ((e = sm_conf_syntax_error(stream, e)) != NULL) fprintf(stderr, "%s\n", e); sm_conf_destroy(stream); return 2; } node = sm_conf_root(stream); if (node != NULL) dump_root(stream, node); sm_conf_destroy(stream); return 0; } int main(int argc, char **argv) { int ai, r; while ((r = getopt(argc, argv, "eqV")) != -1) { switch (r) { case 'e': Equations++; break; case 'q': Noquotes++; break; case 'V': Verbose++; break; default: /* usage(argv[0]); */ return 1; } } argc -= optind; argv += optind; if (argc == 0) return process("*stdin*", stdin); for (ai = 0; ai < argc; ai++) { int ret; ret = process(argv[ai], NULL); if (ret != 0) return ret; } return 0; }