/* * 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-title.c,v 1.2 2005/09/26 23:26:41 ca Exp $") #if SM_LIBCONF_ALONE #include #include #include #include #include "sm-conf.h" #else /* SM_LIBCONF_ALONE */ #include "sm/string.h" #include "sm/sm-conf.h" #include "sm/net.h" #include #endif /* SM_LIBCONF_ALONE */ /* DEMO-TITLE.C -- how to store the title of a section in a variable */ #ifndef offsetof #define offsetof(type, member) ((char *)&((type *)0)->member - (char *)0) #endif typedef struct thing_S { unsigned int t_width, t_height, t_depth; char *t_title; } thing_T; typedef struct stuff_S { unsigned int s_count; char s_label[20]; } stuff_T; typedef struct world_S { stuff_T *w_stuff; size_t w_stuff_n; thing_T *w_thing; size_t w_thing_n; } world_T; static sm_conf_definition_T const thing_contents[] = { { SM_CONF_DEF_MAGIC, "", sm_conf_type_section_title, offsetof(thing_T, t_title), 0, NULL, SM_CONF_FLAG_STRICTLY_REQUIRED }, { SM_CONF_DEF_MAGIC, "height", sm_conf_type_u32, offsetof(thing_T, t_height), sizeof(unsigned int), "1" }, { SM_CONF_DEF_MAGIC, "width", sm_conf_type_u32, offsetof(thing_T, t_width), sizeof(unsigned int), "1" }, { SM_CONF_DEF_MAGIC, "depth", sm_conf_type_u32, offsetof(thing_T, t_depth), sizeof(unsigned int), "1" }, /* sentinel */ { SM_CONF_DEF_MAGIC, NULL } }; static sm_conf_definition_T const stuff_contents[] = { { SM_CONF_DEF_MAGIC, "", sm_conf_type_section_title, offsetof(stuff_T, s_label), 20, NULL }, { SM_CONF_DEF_MAGIC, "count", sm_conf_type_u32, offsetof(stuff_T, s_count), sizeof(unsigned int), "1" }, /* sentinel */ { SM_CONF_DEF_MAGIC, NULL } }; static sm_conf_definition_T const stuff_array[] = { { SM_CONF_DEF_MAGIC, "stuff", sm_conf_type_section, offsetof(world_T, w_stuff), sizeof(stuff_T), NULL, 0, stuff_contents }, { SM_CONF_DEF_MAGIC, "", sm_conf_type_array_n, offsetof(world_T, w_stuff_n), sizeof(size_t) }, /* sentinel */ { SM_CONF_DEF_MAGIC, NULL } }; static sm_conf_definition_T const thing_array[] = { { SM_CONF_DEF_MAGIC, "thing", sm_conf_type_section, offsetof(world_T, w_thing), sizeof(thing_T), NULL, 0, thing_contents }, { SM_CONF_DEF_MAGIC, "", sm_conf_type_array_n, offsetof(world_T, w_thing_n), sizeof(size_t) }, /* sentinel */ { SM_CONF_DEF_MAGIC, NULL } }; static sm_conf_definition_T const world_definition[] = { { SM_CONF_DEF_MAGIC, "thing", sm_conf_type_array, 0, 0, NULL, SM_CONF_FLAG_MULTIPLE, thing_array }, { SM_CONF_DEF_MAGIC, "stuff", sm_conf_type_array, 0, 0, NULL, SM_CONF_FLAG_MULTIPLE, stuff_array }, /* sentinel */ { SM_CONF_DEF_MAGIC, NULL } }; static void print_world(world_T const *w) { size_t i; for (i = 0; i < w->w_stuff_n; i++) { printf("stuff \"%s\": %u\n", w->w_stuff[i].s_label, w->w_stuff[i].s_count); } for (i = 0; i < w->w_thing_n; i++) { printf("thing \"%s\": %u x %u x %u\n", w->w_thing[i].t_title != NULL ? w->w_thing[i].t_title : "(null)", w->w_thing[i].t_width, w->w_thing[i].t_height, w->w_thing[i].t_depth); } } static int process(char const *name, FILE *fp) { sm_conf_T *stream; int err; world_T w; 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(&w, 0, sizeof(w)); err = sm_conf_scan(stream, world_definition, 0, &w); if (err != 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_world(&w); 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; }