/*
* Copyright (c) 2004, 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-isset.c,v 1.6 2005/09/26 23:26:41 ca Exp $")
#if SM_LIBCONF_ALONE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include "sm-conf.h"
#else /* SM_LIBCONF_ALONE */
#include "sm/string.h"
#include "sm/sm-conf.h"
#include "sm/net.h"
#include <stdio.h>
#endif /* SM_LIBCONF_ALONE */
/* DEMO-ISSET.C -- demo sm_conf_scan() */
char const * const opt[] = {
"int_u32",
"unnamed.num",
"sub{foo}sub_u32",
NULL
};
#ifndef offsetof
#define offsetof(type, member) ((char *)&((type *)0)->member - (char *)0)
#endif
typedef struct substructure
{
char const *sub_string;
unsigned int sub_u32;
} substructure;
static sm_conf_definition_T
subdefinitions[] = {
{ SM_CONF_DEF_MAGIC, "sub_u32",
sm_conf_type_u32,
offsetof(substructure, sub_u32),
sizeof(unsigned int),
"1"
},
{ SM_CONF_DEF_MAGIC, "sub_string",
sm_conf_type_string,
offsetof(substructure, sub_string),
0,
"Foo!"
},
/* sentinel */
{ SM_CONF_DEF_MAGIC, NULL }
};
static sm_conf_definition_T
subdefinitions_lefty[] = {
{ SM_CONF_DEF_MAGIC, "sub_lefty",
sm_conf_type_bool,
0,
sizeof(unsigned int),
"yes"
},
/* sentinel */
{ SM_CONF_DEF_MAGIC, NULL }
};
static sm_conf_definition_T
subdefinitions_unnamed[] = {
{ SM_CONF_DEF_MAGIC, "num",
sm_conf_type_u32,
0,
sizeof(unsigned int),
"1"
},
/* sentinel */
{ SM_CONF_DEF_MAGIC, NULL }
};
typedef union vehicle_U
{
enum vehicle_type
{
AIRPLANE = 1,
BOAT = 2,
CAR = 3
} type;
struct
{
enum vehicle_type air_type;
char *air_flight;
int air_passengers;
} airplane;
struct
{
enum vehicle_type boat_type;
int boat_knots;
char *boat_name;
} boat;
struct
{
enum vehicle_type car_type;
int car_mpg;
char *car_plate;
} car;
} vehicle_T;
sm_conf_definition_T const air_definitions[] = {
{ SM_CONF_DEF_MAGIC, "flight", sm_conf_type_string,
offsetof(vehicle_T, airplane.air_flight), 0, NULL
},
{ SM_CONF_DEF_MAGIC, "passengers", sm_conf_type_u32,
offsetof(vehicle_T, airplane.air_passengers),
sizeof(unsigned int), "1"
},
/* sentinel */
{ SM_CONF_DEF_MAGIC, NULL }
};
sm_conf_definition_T const boat_definitions[] = {
{ SM_CONF_DEF_MAGIC, "name", sm_conf_type_string,
offsetof(vehicle_T, boat.boat_name), 0, NULL
},
{ SM_CONF_DEF_MAGIC, "knots", sm_conf_type_u32,
offsetof(vehicle_T, boat.boat_knots),
sizeof(unsigned int), NULL
},
/* sentinel */
{ SM_CONF_DEF_MAGIC, NULL }
};
sm_conf_definition_T const car_definitions[] = {
{ SM_CONF_DEF_MAGIC, "plate", sm_conf_type_string,
offsetof(vehicle_T, car.car_plate), 0, NULL
},
{ SM_CONF_DEF_MAGIC, "mpg", sm_conf_type_u32,
offsetof(vehicle_T, car.car_mpg),
sizeof(unsigned int), NULL
},
/* sentinel */
{ SM_CONF_DEF_MAGIC, NULL }
};
sm_conf_definition_T vehicle_definitions[] = {
{ SM_CONF_DEF_MAGIC, "airplane", sm_conf_type_union_choice, AIRPLANE,
sizeof(vehicle_T), /* default */ NULL, /* flags */ 0,
air_definitions
},
{ SM_CONF_DEF_MAGIC, "boat", sm_conf_type_union_choice, BOAT,
sizeof(vehicle_T), /* default */ NULL, /* flags */ 0,
boat_definitions
},
{ SM_CONF_DEF_MAGIC, "car", sm_conf_type_union_choice, CAR,
sizeof(vehicle_T), /* default */ NULL, /* flags */ 0,
car_definitions
},
/* sentinel */
{ SM_CONF_DEF_MAGIC, NULL }
};
typedef struct
{
unsigned long long_u32;
unsigned int int_u32;
unsigned short short_u32;
unsigned short dice_roll; /* between 2 and 12 */
unsigned long duration;
char const *string;
char suffix[4];
unsigned int bool_true;
unsigned int bool_false;
sm_conf_bytes_T bytes;
unsigned int color;
uint32_t flags;
ipv4_T ipv4;
substructure sub;
unsigned int lefty;
vehicle_T vehicle;
char *twostrings[2];
char **argv;
unsigned int unnamed;
} structure;
sm_conf_definition_T const dice_roll_constraints[] =
{
{ SM_CONF_DEF_MAGIC, "", sm_conf_type_u32_minimum, 2 },
{ SM_CONF_DEF_MAGIC, "", sm_conf_type_u32_maximum, 12 },
/* Sentinel */
{ SM_CONF_DEF_MAGIC, NULL }
};
sm_conf_definition_T const duration_suffixes[] =
{
{ SM_CONF_DEF_MAGIC, "s", sm_conf_type_u32_suffix, 1 },
{ SM_CONF_DEF_MAGIC, "m", sm_conf_type_u32_suffix, 60 },
{ SM_CONF_DEF_MAGIC, "h", sm_conf_type_u32_suffix, 60 * 60 },
{ SM_CONF_DEF_MAGIC, "d", sm_conf_type_u32_suffix, 60 * 60 * 24 },
{ SM_CONF_DEF_MAGIC, "w", sm_conf_type_u32_suffix, 60 * 60 * 24 * 7 },
{ SM_CONF_DEF_MAGIC, "y", sm_conf_type_u32_suffix, 60 * 60 * 24 * 365 },
/* Sentinel */
{ SM_CONF_DEF_MAGIC, NULL }
};
sm_conf_definition_T const color_names[] =
{
{ SM_CONF_DEF_MAGIC, "yellow", sm_conf_type_choice_value, 0xFFFF00},
{ SM_CONF_DEF_MAGIC, "orange", sm_conf_type_choice_value, 0xCCCC00},
{ SM_CONF_DEF_MAGIC, "red", sm_conf_type_choice_value, 0xFF0000},
{ SM_CONF_DEF_MAGIC, "blue", sm_conf_type_choice_value, 0x0000FF},
{ SM_CONF_DEF_MAGIC, "green", sm_conf_type_choice_value, 0x00FF00},
{ SM_CONF_DEF_MAGIC, "brown", sm_conf_type_choice_value, 0x333300},
{ SM_CONF_DEF_MAGIC, "black", sm_conf_type_choice_value, 0x000000},
{ SM_CONF_DEF_MAGIC, "white", sm_conf_type_choice_value, 0xFFFFFF},
/* Sentinel */
{ SM_CONF_DEF_MAGIC, NULL }
};
sm_conf_definition_T const flags_names[] =
{
{ SM_CONF_DEF_MAGIC, "opt1", sm_conf_type_choice_value, 0x000001},
{ SM_CONF_DEF_MAGIC, "opt2", sm_conf_type_choice_value, 0x000002},
{ SM_CONF_DEF_MAGIC, "opt3", sm_conf_type_choice_value, 0x000010},
/* Sentinel */
{ SM_CONF_DEF_MAGIC, NULL }
};
sm_conf_definition_T definitions[] = {
/*
** N U M B E R S
*/
{ SM_CONF_DEF_MAGIC, "long_u32",
sm_conf_type_u32,
offsetof(structure, long_u32),
sizeof(unsigned long),
"1"
},
{ SM_CONF_DEF_MAGIC, "int_u32",
sm_conf_type_u32,
offsetof(structure, int_u32),
sizeof(unsigned int),
"2"
},
{ SM_CONF_DEF_MAGIC, "short_u32",
sm_conf_type_u32,
offsetof(structure, short_u32),
sizeof(unsigned short),
"3"
},
{ SM_CONF_DEF_MAGIC, "ipv4",
sm_conf_type_ipv4,
offsetof(structure, ipv4),
sizeof(ipv4_T),
"0"
},
/* A number that's constrained. */
{ SM_CONF_DEF_MAGIC, "dice_roll",
sm_conf_type_u32,
offsetof(structure, dice_roll),
sizeof(unsigned short),
"7",
0,
dice_roll_constraints
},
/* A number with suffix multipliers. */
{ SM_CONF_DEF_MAGIC, "duration",
sm_conf_type_u32,
offsetof(structure, duration),
sizeof(unsigned long),
"0",
0,
duration_suffixes
},
/*
** S T R I N G S
*/
/* Your basic string. */
{ SM_CONF_DEF_MAGIC, "string",
sm_conf_type_string,
offsetof(structure, string),
0,
"Hello, World?"
},
/* fixed-length string */
{ SM_CONF_DEF_MAGIC, "suffix",
sm_conf_type_string,
offsetof(structure, suffix),
4,
"c"
},
/* argv-style NULL-terminated array, char ** storage. */
{ SM_CONF_DEF_MAGIC, "argv",
sm_conf_type_argv,
offsetof(structure, argv),
0
},
/* argv-style NULL-terminated array, char *[] storage. */
{ SM_CONF_DEF_MAGIC, "twostrings",
sm_conf_type_argv,
offsetof(structure, twostrings),
2
},
/*
** B O O L E A N
*/
{ SM_CONF_DEF_MAGIC, "bool_true",
sm_conf_type_bool,
offsetof(structure, bool_true),
sizeof(unsigned int),
"true"
},
{ SM_CONF_DEF_MAGIC, "bool_false",
sm_conf_type_bool,
offsetof(structure, bool_false),
sizeof(unsigned int),
"false"
},
/*
** B Y T E S T R I N G
*/
{ SM_CONF_DEF_MAGIC, "bytes",
sm_conf_type_bytes,
offsetof(structure, bytes)
},
/*
** E N U M
*/
{ SM_CONF_DEF_MAGIC, "color",
sm_conf_type_choice,
offsetof(structure, color),
sizeof(unsigned int),
"green",
0,
color_names
},
{ SM_CONF_DEF_MAGIC, "flags",
sm_conf_type_choice,
offsetof(structure, flags),
sizeof(uint32_t),
"0",
SM_CONF_FLAG_MULTIPLE | SM_CONF_FLAG_NUMERIC,
flags_names
},
/*
** S E C T I O N
*/
{ SM_CONF_DEF_MAGIC, "sub",
sm_conf_type_section,
offsetof(structure, sub),
sizeof(struct substructure),
NULL, 0, subdefinitions
},
{ SM_CONF_DEF_MAGIC, "sub{lefty}",
sm_conf_type_section,
offsetof(structure, lefty),
sizeof(unsigned int),
NULL, 0, subdefinitions_lefty
},
{ SM_CONF_DEF_MAGIC, "unnamed",
sm_conf_type_section,
offsetof(structure, unnamed),
sizeof(unsigned int),
NULL, 0, subdefinitions_unnamed
},
/*
** U N I O N
*/
{ SM_CONF_DEF_MAGIC, "vehicle",
sm_conf_type_union,
offsetof(structure, vehicle.type),
sizeof(enum vehicle_type),
NULL, 0, vehicle_definitions
},
/* sentinel */
{ SM_CONF_DEF_MAGIC, NULL }
};
#if 0
static void
print_structure(structure *s)
{
size_t i;
printf("long_u32: %lu\n", s->long_u32);
printf("int_u32: %u\n", s->int_u32);
printf("short_u32: %hu\n", s->short_u32);
printf("ipv4: %X\n", (unsigned int) htonl(s->ipv4));
printf("dice_roll: %hu\n", s->dice_roll);
printf("duration: %lu\n", s->duration);
printf("string: '%s'\n", s->string);
printf("suffix: '%s'\n", s->suffix);
printf("bool_true: '%d'\n", s->bool_true);
printf("bool_false: '%d'\n", s->bool_false);
printf("bytes: [%d]", (int)s->bytes.scb_size);
for (i = 0; i < s->bytes.scb_size; i++)
printf(" %2.2hx", (unsigned char)s->bytes.scb_data[i]);
putchar('\n');
printf("color: 0x%6.6x\n", s->color);
printf("flags: 0x%6.6x\n", s->flags);
printf("sub.sub_u32: %d\n", s->sub.sub_u32);
printf("sub.sub_string: %s\n", s->sub.sub_string);
printf("lefty: %d\n", s->lefty);
printf("argv:");
if (s->argv == NULL)
fputs(" NULL", stdout);
else
for (i = 0; s->argv[i] != NULL; i++)
printf(" '%s'", s->argv[i]);
putchar('\n');
printf("twostrings:");
for (i = 0; i < 2 && s->twostrings[i] != NULL; i++)
printf(" '%s'", s->twostrings[i]);
putchar('\n');
}
#endif /* 0 */
static int
process(char const *name, FILE *fp)
{
sm_conf_T *stream;
int err;
int val;
size_t i;
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;
}
for (i = 0; opt[i] != NULL; i++)
{
val = 0;
err = sm_conf_get(stream, opt[i], sm_conf_type_u32, NULL, 0,
&val, sizeof val);
if (err)
{
char buf[200];
printf("%s: %s\n", opt[i],
sm_conf_strerror(err, buf, sizeof buf));
}
else
{
printf("%s: ok.\n", opt[i]);
}
}
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