/*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sm-conf.h"
#else /* SM_LIBCONF_ALONE */
#include "sm/string.h"
#include "sm/sm-conf.h"
#include <stdio.h>
#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;
}
syntax highlighted by Code2HTML, v. 0.9.1