/*
 * 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: demo-flagzoo.c,v 1.4 2004/05/18 02:31:57 jutta 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 */

/* DEMO-FLAGZOO.C -- demo the different flags. */

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

typedef struct
{
	unsigned int		y;
} subsubstructure;

typedef struct {

	unsigned int		x;
	subsubstructure		s;

} substructure;

typedef struct
{
	substructure		allow_any_option;
	substructure		allow_any_section;
	substructure		allow_any;
	substructure		allow_none;

} structure;

sm_conf_definition_T
subsubsection_definition[] =
{

	{ SM_CONF_DEF_MAGIC,
		"y",
		sm_conf_type_u32,
		0,
		sizeof(unsigned int)
	},

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

sm_conf_definition_T
subsection_definition[] =
{

	{ SM_CONF_DEF_MAGIC,
		"x",
		sm_conf_type_u32,
		0,
		sizeof(unsigned int)
	},

	{ SM_CONF_DEF_MAGIC,
		"s",
		sm_conf_type_section,
		offsetof(substructure, s),
		sizeof(((substructure *)0)->s),
		NULL,
		0,
		subsubsection_definition
	},

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

sm_conf_definition_T
definitions[] =
{

	{ SM_CONF_DEF_MAGIC,
		"SM_CONF_FLAG_ALLOW_ANY_SECTION",
		sm_conf_type_section,
		offsetof(structure, allow_any_section),
		0,
		NULL,
		SM_CONF_FLAG_ALLOW_ANY_SECTION,
		subsection_definition
	},

	{ SM_CONF_DEF_MAGIC,
		"SM_CONF_FLAG_ALLOW_ANY_OPTION",
		sm_conf_type_section,
		offsetof(structure, allow_any_option),
		0,
		NULL,
		SM_CONF_FLAG_ALLOW_ANY_OPTION,
		subsection_definition
	},

	{ SM_CONF_DEF_MAGIC,
		"SM_CONF_FLAG_ALLOW_ANY",
		sm_conf_type_section,
		offsetof(structure, allow_any),
		0,
		NULL,
		SM_CONF_FLAG_ALLOW_ANY,
		subsection_definition
	},

	{ SM_CONF_DEF_MAGIC,
		"SM_CONF_FLAG_ALLOW_NONE",
		sm_conf_type_section,
		offsetof(structure, allow_none),
		0,
		NULL,
		0,
		subsection_definition
	},

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

static void
print_structure(structure *s)
{
	printf("allow-any-section: %d %d\n",
		s->allow_any_section.x,
		s->allow_any_section.s.y);
	printf("allow-any-option: %d %d\n",
		s->allow_any_option.x,
		s->allow_any_option.s.y);
	printf("allow-any: %d %d\n",
		s->allow_any.x,
		s->allow_any.s.y);
	printf("allow-none: %d %d\n",
		s->allow_none.x,
		s->allow_none.s.y);
}

static int
process(char const *name, FILE *fp)
{
	sm_conf_T		*stream;
	int			err;
	structure		s;

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

	memset(&s, 0, sizeof(s));
	if ((err = sm_conf_scan(stream, definitions, 0, &s)) != 0)
	{
		char buf[SM_CONF_ERROR_BUFFER_SIZE];
		char const *e = NULL;

		fprintf(stderr, "(while scanning) %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 3;
	}

	print_structure(&s);
	sm_conf_destroy(stream);

	return 0;
}

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

	if (ac == 1)
		return process("*stdin*", stdin);

	for (ai = 1; ai < ac; ai++)
	{
		int ret = process(av[ai], NULL);
		if (ret != 0)
			return ret;
	}
	return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1