/*
 * Copyright (c) 2005 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: demo-walk-n-scan.c,v 1.3 2005/09/26 23:26:41 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/sm-conf.h"
#endif /* SM_LIBCONF_ALONE */

/* SCANNER.C -- demo sm_conf_scan() */

#ifndef offsetof
#define offsetof(type, member)	((char *)&((type *)0)->member - (char *)0)
#endif

typedef struct
{
	short	fl_price;
	char	*fl_color;
} flavor;

sm_conf_definition_T
flavor_def[] =
{
	{ SM_CONF_DEF_MAGIC,
		"price",
		sm_conf_type_u32,
		offsetof(flavor, fl_price),
		sizeof(short),
	},

	{ SM_CONF_DEF_MAGIC,
		"color",
		sm_conf_type_string,
		offsetof(flavor, fl_color),
		0,
		"transparent"
	},

	/* sentinel */
	{ SM_CONF_DEF_MAGIC, NULL }
};

static void
print_flavor(flavor *f)
{
	printf("\tprice: %hu\n", f->fl_price);
	printf("\tcolor: %s\n", f->fl_color);
}

static int
process(char const *name, FILE *fp)
{
	sm_conf_T		*stream;
	int			err;
	flavor			f;
	sm_conf_node_T		*node, *root;

	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;
	}

	root = sm_conf_root(stream);
	node = NULL;

	while ((node = sm_conf_section_next_subsection(
		stream, root, NULL, 0, NULL, 0, node)) != NULL)
	{
		if ((err = sm_conf_get_relative(stream, node, "",
			sm_conf_type_section, flavor_def, 0,
			&f, sizeof f)) != 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;
		}
		else
		{
			print_flavor(&f);
		}
	}

	sm_conf_destroy(stream);
	return 0;
}

int
main(int ac, char **av)
{
	int	ret;
	int	ai;

	ret = 0;
	if (ac == 1)
		ret = process("*stdin*", stdin);
	else
	{
		for (ai = 1; ai < ac; ai++)
		{
			ret = process(av[ai], NULL);
			if (ret != 0)
				break;
		}
	}

	return ret;
}


syntax highlighted by Code2HTML, v. 0.9.1