Subject: Re: XML config file
To: Jason Thorpe <thorpej@shagadelic.org>
From: Jason Thorpe <thorpej@shagadelic.org>
List: tech-userlevel
Date: 07/24/2006 11:07:34
On Jul 23, 2006, at 2:03 PM, Jason Thorpe wrote:
> The stuff I've been playing around with looks a bit like this:
Ok, I fleshed it out a bit more.
typedef enum {
PROP_INGEST_ERROR_NO_ERROR = 0,
PROP_INGEST_ERROR_NO_KEY = 1,
PROP_INGEST_ERROR_WRONG_TYPE = 2,
PROP_INGEST_ERROR_HANDLER_FAILED = 3
} prop_ingest_error_t;
typedef struct _prop_ingest_context *prop_ingest_context_t;
typedef boolean_t (*prop_ingest_handler_t)(prop_ingest_context_t,
prop_object_t);
typedef struct {
const char *pite_key;
prop_type_t pite_type;
prop_ingest_handler_t pite_handler;
} prop_ingest_table_entry;
#define PROP_INGEST(key_, type_,
handler_) \
{ .pite_key =
key_ , \
.pite_type =
type_ , \
.pite_handler = handler_ }
#define
PROP_INGEST_END \
{ .pite_key = NULL }
prop_ingest_context_t
prop_ingest_context_alloc(void *);
void prop_ingest_context_free(prop_ingest_context_t);
prop_ingest_error_t
prop_ingest_context_error(prop_ingest_context_t);
prop_type_t prop_ingest_context_type(prop_ingest_context_t);
const char * prop_ingest_context_key(prop_ingest_context_t);
void * prop_ingest_context_private(prop_ingest_context_t);
boolean_t prop_dictionary_ingest(prop_dictionary_t,
prop_ingest_table_entry[],
void *);
...
static prop_ingest_table_entry bsd44_geom_ingest_table[] = {
.
.
.
PROP_INGEST("sectors-per-unit", PROP_TYPE_NUMBER,
bsd44_geom_sectors_per_unit),
.
.
.
PROP_INGEST_END
};
static boolean_t
bsd44_geom_sectors_per_unit(prop_ingest_context_t ctx,
prop_object_t obj)
{
struct bsd44_ingest_context *bsd44ctx =
prop_ingest_context_private(ctx);
struct disklabel *lp = bsd44ctx->label;
uint64_t val;
val = prop_number_integer_value(obj);
if (val > 0xffffffff) {
bsd44ctx->errorstr =
"sectors-per-unit exceeds maximum allowed value";
return (FALSE);
}
lp->d_secperunit = (uint32_t)(val & 0xffffffff);
return (TRUE);
}
...
{
...
struct disklabel *lp;
bsd44_ingest_context bsd44ctx;
prop_ingest_context_t ctx;
...
geom_dict = prop_dictionary_get(props, "disk-geometry");
if (prop_object_type(geom_dict) != PROP_TYPE_DICTIONARY) {
/* return an error */
}
bsd44ctx.lp = lp;
bsd44ctx.errorstr = NULL;
ctx = prop_ingest_context_alloc(&bsd44ctx);
if (ctx == NULL) {
/* return an error */
}
if (prop_dictionary_ingest(geom_dict,
bsd44_geom_ingest_table,
ctx) == FALSE) {
/* report error */
switch (prop_ingest_context_error(ctx)) {
case PROP_INGEST_ERROR_NO_KEY:
/* prop_ingest_context_key(ctx)
returns the key that was missing. */
break;
case PROP_INGEST_ERROR_WRONG_TYPE:
/* prop_ingest_context_key(ctx)
returns the key that failed and
prop_ingest_context_type(ctx)
returns the ACTUAL type of that
key's object. */
break;
case PROP_INGEST_ERROR_HANDLER_FAILED:
/* Our handler filled in
bsd44ctx.errorstr */
break;
default:
/* can't happen */
break;
}
}
-- thorpej