/*
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: t-dyn-0.c,v 1.4 2006/12/25 03:30:27 ca Exp $")

#include "sm/string.h"
#include "sm/net.h"
#include "sm/units.h"
#include "sm/sm-conf.h"
#define SM_CONF_BYTE_DEF 1
#define SM_CONF_KBYTE_DEF 1
#include "sm/sm-conf-byte.h"
#include "sm/sm-conf-prt.h"
#include "sm/sysexits.h"
#include "sm/io.h"
#include "sm/test.h"

#if SM_HEAP_CHECK
extern SM_DEBUG_T SmHeapCheck;
# define HEAP_CHECK (SmHeapCheck > 0)
#else
# define HEAP_CHECK 0
#endif


/*
**  Just a test program to play around with libconf: read from a buffer
*/

typedef struct
{
	int        rhs_greet_pause;
	int        rhs_access_code;
	uint32_t   rhs_flags;
} rhs_T;

sm_conf_definition_T const rhs_flag_names[] =
{
{ SM_CONF_DEF_MAGIC, "grey_listing",	sm_conf_type_choice_value, 0x01	},
{ SM_CONF_DEF_MAGIC, "EHLO_checks",		sm_conf_type_choice_value, 0x02 },

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


static sm_conf_definition_T defs[] =
{
	{ SM_CONF_DEF_MAGIC, "flags", sm_conf_type_choice,
		offsetof(rhs_T, rhs_flags), sizeof(uint32_t), NULL,
		SM_CONF_FLAG_MULTIPLE, rhs_flag_names,
		NULL, NULL,
		"tests"
	},


{ SM_CONF_DEF_MAGIC, "greet_pause",	sm_conf_type_u32,
	offsetof(rhs_T, rhs_greet_pause),	sizeof(int),	"0",
	0,	NULL,	NULL,	NULL,
	"delay sending greeting"	},

{ SM_CONF_DEF_MAGIC, "reply_code",	sm_conf_type_u32,
	offsetof(rhs_T, rhs_access_code),	sizeof(int),	"0",
	0,	NULL,	NULL,	NULL,
	"SMTP reply code"	},

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

static rhs_T rhs;

static void
print_structure(rhs_T *rhs)
{
	sm_conf_prt_conf(defs, rhs, smioerr);
}


static int
process(char *data, int show)
{
	sm_conf_T *sm_conf;
	int err;
	char buf[SM_CONF_ERROR_BUFFER_SIZE];
	char const *e = NULL;
	const char *name = "rhs";

	if (NULL == data) {
		data = "";
	}
	sm_conf = sm_conf_new(name);
	SM_TEST_E(sm_conf != NULL);
	err = sm_conf_read_data(sm_conf, data, strlen(data), true);
	SM_TEST(0 == err);
	if (err != 0) {
		sm_io_fprintf(smioerr, "%s: %s\n", name,
			sm_conf_strerror(err, buf, sizeof buf));

		while ((e = sm_conf_syntax_error(sm_conf, e)) != NULL)
			sm_io_fprintf(smioerr, "%s\n", e);

		sm_conf_destroy(sm_conf);
		return 2;
	}

	err = sm_conf_scan(sm_conf, defs, 0, &rhs);
	if (err != 0) {
		sm_io_fprintf(smioerr, "(while scanning) %s: %s\n", name,
			sm_conf_strerror(err, buf, sizeof buf));

		while ((e = sm_conf_syntax_error(sm_conf, e)) != NULL)
			sm_io_fprintf(smioerr, "%s\n", e);

		sm_conf_destroy(sm_conf);
		return 3;
	}

	if (show)
		print_structure(&rhs);

	sm_conf_destroy(sm_conf);
	return 0;

  error:
	if (sm_conf != NULL)
		sm_conf_destroy(sm_conf);
	return -1;
}

int
main(int argc, char **argv)
{
	int ai, c, done, ret;

	done = 0;
	ret = 0;
#if SM_HEAP_CHECK
	SmHeapCheck = 0;
#endif
	while ((c = getopt(argc, argv, "H:h")) != -1)
	{
		switch (c)
		{
#if SM_HEAP_CHECK
		  case 'H':
			SmHeapCheck = atoi(optarg);
			break;
#endif
		  case 'h':
			/* usage(argv[0]); */
			exit(EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;

	if (argc == 0)
		ret = process(NULL, 1);
	else {
		for (ai = 0; ai < argc; ai++)
		{

			ret = process(argv[ai], 1);
			if (ret != 0)
				break;
		}
	}
#if SM_HEAP_CHECK
	if (HEAP_CHECK) {
		sm_io_fprintf(smioout, "heap should be empty except for makebuf:\n");
		sm_heap_report(smioout, 3);
	}
#endif
	sm_io_flush(smioout);
	return ret;
}


syntax highlighted by Code2HTML, v. 0.9.1