Commit 30053543 authored by Bernhard Link's avatar Bernhard Link

refactor some code to have a tiny little bit more type safety

parent 32088b32
......@@ -317,7 +317,7 @@ static size_t printLISTofCARD16(struct connection *c,const uint8_t *buffer,size_
putc(',',out);
notfirst = true;
u16 = getCARD16(ofs);
value = findConstant(p->constants,u16);
value = findConstant(p->o.constants, u16);
if( value )
fprintf(out,"%s(0x%hx)",value,(unsigned short int)u16);
else
......@@ -352,7 +352,7 @@ static size_t printLISTofCARD32(struct connection *c,const uint8_t *buffer,size_
putc(',',out);
notfirst = true;
u32 = getCARD32(ofs);
value = findConstant(p->constants,u32);
value = findConstant(p->o.constants, u32);
if( value )
fprintf(out,"%s(0x%x)",value,(unsigned int)u32);
else
......@@ -486,7 +486,7 @@ static size_t printLISTofATOM(struct connection *c,const uint8_t *buffer,size_t
putc(',',out);
notfirst = true;
u32 = getCARD32(ofs);
value = findConstant(p->constants,u32);
value = findConstant(p->o.constants, u32);
if( value )
fprintf(out,"%s(0x%x)",value,(unsigned int)u32);
else if( (value = getAtom(c,u32)) == NULL )
......@@ -523,7 +523,7 @@ static size_t printLISTofINT8(const uint8_t *buffer,size_t buflen,const struct p
putc(',',out);
notfirst = true;
i8 = getCARD8(ofs);
value = findConstant(p->constants,i8);
value = findConstant(p->o.constants, i8);
if( value )
fprintf(out,"%s(%d)",value,(int)i8);
else
......@@ -558,7 +558,7 @@ static size_t printLISTofINT16(struct connection *c,const uint8_t *buffer,size_t
putc(',',out);
notfirst = true;
i16 = getCARD16(ofs);
value = findConstant(p->constants,i16);
value = findConstant(p->o.constants, i16);
if( value )
fprintf(out,"%s(%d)",value,(int)i16);
else
......@@ -593,7 +593,7 @@ static size_t printLISTofINT32(struct connection *c,const uint8_t *buffer,size_t
putc(',',out);
notfirst = true;
i32 = getCARD32(ofs);
value = findConstant(p->constants,i32);
value = findConstant(p->o.constants, i32);
if( value )
fprintf(out,"%s(%d)",value,(int)i32);
else
......@@ -628,7 +628,7 @@ static size_t printLISTofUINT8(const uint8_t *buffer,size_t buflen,const struct
putc(',',out);
notfirst = true;
u8 = getCARD8(ofs);
value = findConstant(p->constants,u8);
value = findConstant(p->o.constants, u8);
if( value )
fprintf(out,"%s(%u)",value,(unsigned int)u8);
else
......@@ -663,7 +663,7 @@ static size_t printLISTofUINT16(struct connection *c,const uint8_t *buffer,size_
putc(',',out);
notfirst = true;
u16 = getCARD16(ofs);
value = findConstant(p->constants,u16);
value = findConstant(p->o.constants, u16);
if( value )
fprintf(out,"%s(%u)",value,(unsigned int)u16);
else
......@@ -698,7 +698,7 @@ static size_t printLISTofUINT32(struct connection *c,const uint8_t *buffer,size_
putc(',',out);
notfirst = true;
u32 = getCARD32(ofs);
value = findConstant(p->constants,u32);
value = findConstant(p->o.constants, u32);
if( value )
fprintf(out,"%s(%u)",value,(unsigned int)u32);
else
......@@ -712,7 +712,7 @@ static size_t printLISTofUINT32(struct connection *c,const uint8_t *buffer,size_
static size_t printLISTofVALUE(struct connection *c,const uint8_t *buffer,size_t buflen,const struct parameter *param,unsigned long valuemask, size_t ofs){
const struct value *v = (const struct value*)param->constants;
const struct value *v = param->o.values;
const char *atom;
bool notfirst = false;
......@@ -858,9 +858,7 @@ static size_t print_parameters(struct connection *c, const unsigned char *buffer
static size_t printLISTofStruct(struct connection *c,const uint8_t *buffer,size_t buflen,const struct parameter *p,size_t count, size_t ofs, struct stack *stack){
bool notfirst = false;
/* This is a gross hack: the constants for ft_LISTofStruct are
* in reality a parameter structure */
const struct parameter *substruct = (const void*)p->constants;
const struct parameter *substruct = p->o.parameters;
size_t len;
size_t nr = 0;
......@@ -898,7 +896,7 @@ static size_t printLISTofStruct(struct connection *c,const uint8_t *buffer,size_
static size_t printLISTofVarStruct(struct connection *c,const uint8_t *buffer,size_t buflen,const struct parameter *p,size_t count, size_t ofs, struct stack *stack){
bool notfirst = false;
// size_t ofs = (p->offset<0)?lastofs:p->offset;
const struct parameter *substruct = (const void*)p->constants;
const struct parameter *substruct = p->o.parameters;
size_t len;
size_t nr = 0;
......@@ -1005,7 +1003,7 @@ static size_t print_parameters(struct connection *c, const unsigned char *buffer
continue;
/* some more overloading: */
if( v == (unsigned char)(p->name[0]) )
p = ((struct parameter *)p->constants)-1;
p = (p->o.parameters)-1;
continue;
} else if( p->type == ft_IF16 ) {
unsigned int v;
......@@ -1018,7 +1016,7 @@ static size_t print_parameters(struct connection *c, const unsigned char *buffer
continue;
if( v == (unsigned char)(p->name[1])
+ (unsigned int)0x100*(unsigned char)(p->name[0]) )
p = ((struct parameter *)p->constants)-1;
p = (p->o.parameters)-1;
continue;
} else if( p->type == ft_IF32 ) {
unsigned long v;
......@@ -1033,7 +1031,7 @@ static size_t print_parameters(struct connection *c, const unsigned char *buffer
+ (((unsigned long)((unsigned char)(p->name[2])))<<8)
+ (((unsigned long)((unsigned char)(p->name[1])))<<16)
+ (((unsigned long)((unsigned char)(p->name[0])))<<24) )
p = ((struct parameter *)p->constants)-1;
p = (p->o.parameters)-1;
continue;
} else if( p->type == ft_IFATOM ) {
const char *atomname;
......@@ -1046,7 +1044,7 @@ static size_t print_parameters(struct connection *c, const unsigned char *buffer
if( atomname == NULL )
continue;
if( strcmp(atomname, p->name) == 0 )
p = ((struct parameter *)p->constants)-1;
p = (p->o.parameters)-1;
continue;
}
......@@ -1087,7 +1085,7 @@ static size_t print_parameters(struct connection *c, const unsigned char *buffer
continue;
case ft_LISTofCARD8:
lastofs = printLISTofCARD8(buffer, len,
p->name, p->constants,
p->name, p->o.constants,
stored, ofs);
continue;
case ft_LISTofCARD16:
......@@ -1121,7 +1119,7 @@ static size_t print_parameters(struct connection *c, const unsigned char *buffer
switch( format ) {
case 8:
lastofs = printLISTofCARD8(buffer, len,
p->name, p->constants,
p->name, p->o.constants,
stored, ofs);
break;
case 16:
......@@ -1232,7 +1230,7 @@ static size_t print_parameters(struct connection *c, const unsigned char *buffer
fprintf(out,"[%d]",(int)ofs);
fputs(p->name,out);putc('=',out);
u32 = getCARD32(ofs);
value = findConstant(p->constants,u32);
value = findConstant(p->o.constants, u32);
atom = getAtom(c, u32);
if( value != NULL )
fprintf(out,"%s(0x%x)",value, (unsigned int)u32);
......@@ -1292,7 +1290,7 @@ static size_t print_parameters(struct connection *c, const unsigned char *buffer
}
if( p->type >= ft_BITMASK8 ) {
assert(p->type <= ft_BITMASK32 );
print_bitfield(p->name,p->constants,l);
print_bitfield(p->name, p->o.constants, l);
continue;
}
if( p->type >= ft_PUSH8 ) {
......@@ -1310,7 +1308,7 @@ static size_t print_parameters(struct connection *c, const unsigned char *buffer
continue;
}
}
value = findConstant(p->constants,l);
value = findConstant(p->o.constants, l);
if( print_offsets )
fprintf(out,"[%d]",(int)ofs);
fputs(p->name,out);putc('=',out);
......
......@@ -46,6 +46,7 @@ struct parameter {
* applies to. If OFS_LATER it is after the last list item
* in this parameter-list. */
size_t offse;
/* NULL means end of list */
const char *name;
enum fieldtype {
/* signed endian specific: */
......@@ -130,7 +131,14 @@ struct parameter {
ft_DECREMENT_STORED,
ft_SET
} type;
const struct constant *constants;
union parameter_option {
/* for integers and fields of integers */
const struct constant *constants;
/* for IFs, Structs, ... */
const struct parameter *parameters;
/* for LISTofVALUE */
const struct value *values;
} o;
};
struct value {
unsigned long flag;
......
......@@ -149,7 +149,7 @@ struct variable {
const char *condition;
bool isjunction;
struct unfinished_parameter *iftrue;
const void *finalized;
const struct parameter *finalized;
} special;
};
} *parameter;
......@@ -166,7 +166,7 @@ struct variable {
} *values;
struct typespec t;
};
const void *finalized;
union parameter_option finalized;
};
struct namespace {
......@@ -2270,13 +2270,13 @@ bool parser_free(struct parser *parser) {
return success;
}
static const void *variable_finalize(struct parser *, struct variable *);
static void variable_finalize(struct parser *, struct variable *, union parameter_option *);
static const void *parameter_finalize(struct parser *parser, struct unfinished_parameter *parameter) {
static const struct parameter *parameter_finalize(struct parser *parser, struct unfinished_parameter *parameter) {
struct unfinished_parameter *p;
size_t count = 0;
struct parameter *prepared, *f;
const void *finalized;
const struct parameter *finalized;
/* no need to do add empty ones all the time,
just take the last one... */
static const struct parameter *empty = NULL;
......@@ -2301,13 +2301,12 @@ static const void *parameter_finalize(struct parser *parser, struct unfinished_p
f->offse = p->special.offse;
f->name = p->special.condition;
f->type = p->special.type;
f->constants = p->special.finalized;
f->o.parameters = p->special.finalized;
} else {
f->offse = p->regular.offse;
f->name = p->regular.name;
f->type = p->regular.type.base_type->type;
f->constants = variable_finalize(parser,
p->regular.type.data);
variable_finalize(parser, p->regular.type.data, &f->o);
}
}
assert( (size_t)(f - prepared) == count );
......@@ -2321,96 +2320,125 @@ static const void *parameter_finalize(struct parser *parser, struct unfinished_p
return finalized;
}
static const void *variable_finalize(struct parser *parser, struct variable *v) {
static const struct parameter *parameters_finalize(struct parser *parser, struct variable *v) {
struct unfinished_parameter *p, *todo, *startat;
if( v == NULL )
return NULL;
if( v->finalized != NULL )
return v->finalized;
if( v->type == vt_values ) {
struct value *values;
struct unfinished_value *uv;
size_t i = 0, count = 0;
assert( v->type == vt_struct || v->type == vt_response ||
v->type == vt_setup ||
v->type == vt_request || v->type == vt_event );
if( v->finalized.parameters != NULL )
return v->finalized.parameters;
do {
todo = NULL;
startat = v->parameter;
p = startat;
for( uv = v->values; uv != NULL ; uv = uv->next )
count++;
values = calloc(count + 1, sizeof(struct value));
if( values == NULL ) {
oom(parser);
return NULL;
while( p != NULL ) {
if( !p->isspecial ) {
p = p->next;
continue;
}
if( p->special.finalized != NULL ) {
p = p->next;
continue;
}
if( !p->special.isjunction ) {
p = p->next;
continue;
}
if( p->special.iftrue == NULL ) {
/* empty branch still needs
an end command, but no recursion
for that */
p->special.finalized =
parameter_finalize(parser, NULL);
p = p->next;
continue;
}
todo = p;
startat = p->special.iftrue;
p = startat;
}
for( uv = v->values; uv != NULL ; uv = uv->next ) {
assert( i < count);
values[i].flag = uv->flag;
values[i].name = uv->name;
assert( C(uv->type.base_type, ELEMENTARY) );
values[i].type = uv->type.base_type->type;
values[i].constants = variable_finalize(
parser, uv->type.data);
i++;
}
v->finalized = finalize_data(values, (count+1)*sizeof(struct value),
__alignof__(struct value));
free(values);
if( v->finalized == NULL )
parser->error = true;
return v->finalized;
}
if( v->type == vt_constants ) {
v->finalized = finalize_data(v->c.constants,
v->c.size, __alignof__(struct constant));
if( v->finalized == NULL )
parser->error = true;
return v->finalized;
if( todo != NULL ) {
todo->special.finalized =
parameter_finalize(parser, startat);
} else {
v->finalized.parameters =
parameter_finalize(parser, startat);
}
} while( todo != NULL );
return v->finalized.parameters;
}
static const struct constant *constants_finalize(struct parser *parser, struct variable *v) {
if( v == NULL )
return NULL;
assert( v->type == vt_constants );
if( v->finalized.constants != NULL )
return v->finalized.constants;
v->finalized.constants = finalize_data(v->c.constants,
v->c.size, __alignof__(struct constant));
if( v->finalized.constants == NULL )
parser->error = true;
return v->finalized.constants;
}
static inline const struct value *values_finalize(struct parser *parser, struct variable *v) {
struct value *values;
struct unfinished_value *uv;
size_t i = 0, count = 0;
if( v == NULL )
return NULL;
assert( v->type == vt_values );
if( v->finalized.values != NULL )
return v->finalized.values;
for( uv = v->values; uv != NULL ; uv = uv->next )
count++;
values = calloc(count + 1, sizeof(struct value));
if( values == NULL ) {
oom(parser);
return NULL;
}
if( v->type == vt_struct || v->type == vt_response ||
for( uv = v->values; uv != NULL ; uv = uv->next ) {
assert( i < count);
values[i].flag = uv->flag;
values[i].name = uv->name;
assert( C(uv->type.base_type, ELEMENTARY) );
values[i].type = uv->type.base_type->type;
values[i].constants = constants_finalize(
parser, uv->type.data);
i++;
}
v->finalized.values = finalize_data(values,
(count+1)*sizeof(struct value),
__alignof__(struct value));
free(values);
if( v->finalized.values == NULL )
parser->error = true;
return v->finalized.values;
}
static void variable_finalize(struct parser *parser, struct variable *v, union parameter_option *o) {
if( v == NULL ) {
memset(o, 0, sizeof(union parameter_option));
} else if( v->type == vt_values ) {
o->values = values_finalize(parser, v);
} else if( v->type == vt_constants ) {
o->constants = constants_finalize(parser, v);
} else if( v->type == vt_struct || v->type == vt_response ||
v->type == vt_setup ||
v->type == vt_request || v->type == vt_event ) {
struct unfinished_parameter *p, *todo, *startat;
do {
todo = NULL;
startat = v->parameter;
p = startat;
while( p != NULL ) {
if( !p->isspecial ) {
p = p->next;
continue;
}
if( p->special.finalized != NULL ) {
p = p->next;
continue;
}
if( !p->special.isjunction ) {
p = p->next;
continue;
}
if( p->special.iftrue == NULL ) {
/* empty branch still needs
an end command, but no recursion
for that */
p->special.finalized =
parameter_finalize(
parser,
NULL);
p = p->next;
continue;
}
todo = p;
startat = p->special.iftrue;
p = startat;
}
if( todo != NULL ) {
todo->special.finalized =
parameter_finalize(parser, startat);
} else {
v->finalized =
parameter_finalize(parser, startat);
}
} while( todo != NULL );
return v->finalized;
o->parameters = parameters_finalize(parser, v);
} else {
memset(o, 0, sizeof(union parameter_option));
assert( v->type != v->type );
}
assert( v->type != v->type );
}
static const struct request *finalize_requests(struct parser *parser, struct namespace *ns, const struct parameter *unknownrequest, const struct parameter *unknownresponse) {
......@@ -2430,7 +2458,7 @@ static const struct request *finalize_requests(struct parser *parser, struct nam
rs[i].parameters = unknownrequest;
} else {
assert( ns->requests[i].request != NULL);
rs[i].parameters = variable_finalize(parser,
rs[i].parameters = parameters_finalize(parser,
ns->requests[i].request);
}
if( ns->requests[i].has_response ) {
......@@ -2439,7 +2467,7 @@ static const struct request *finalize_requests(struct parser *parser, struct nam
rs[i].answers = unknownresponse;
} else {
assert( ns->requests[i].response != NULL);
rs[i].answers = variable_finalize(parser,
rs[i].answers = parameters_finalize(parser,
ns->requests[i].response);
}
} else
......@@ -2489,7 +2517,7 @@ static const struct event *finalize_events(struct parser *parser, struct namespa
}
for( i = 0 ; i < ns->num_events[et] ; i++ ) {
es[i].name = ns->events[et][i].name;
es[i].parameters = variable_finalize(parser,
es[i].parameters = parameters_finalize(parser,
ns->events[et][i].event);
if( !ns->events[et][i].special )
continue;
......@@ -2563,9 +2591,9 @@ void finalize_everything(struct parser *parser) {
return;
}
v = find_variable(parser, vt_request, "core::unknown");
unknownrequest = variable_finalize(parser, v);
unknownrequest = parameters_finalize(parser, v);
v = find_variable(parser, vt_response, "core::unknown");
unknownresponse = variable_finalize(parser, v);
unknownresponse = parameters_finalize(parser, v);
unexpected_reply = unknownresponse;
if( parser->error )
return;
......@@ -2622,7 +2650,7 @@ void finalize_everything(struct parser *parser) {
if( errors == NULL )
parser->error = true;
num_errors = core->num_errors;
setup_parameters = variable_finalize(parser, core->setup);
setup_parameters = parameters_finalize(parser, core->setup);
}
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment