From 86bbd12c3889db3290e22ff61934ca1a218ce114 Mon Sep 17 00:00:00 2001 From: cnlohr Date: Fri, 27 Apr 2018 21:42:05 -0400 Subject: New config system --- src/survive_config.c | 267 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 213 insertions(+), 54 deletions(-) (limited to 'src/survive_config.c') diff --git a/src/survive_config.c b/src/survive_config.c index 92c0125..23433c4 100644 --- a/src/survive_config.c +++ b/src/survive_config.c @@ -28,28 +28,32 @@ struct static_conf_t }; static struct static_conf_t static_configs[MAX_SHORTHAND_CONFIGS]; +int nr_static_configs; -void survive_config_bind_variable( char vt, int * variable, const char * name, const char * description, ... ) +void survive_config_bind_variable( char vt, const char * name, const char * description, ... ) { va_list ap; va_start(ap, description); int i; struct static_conf_t * config; - for( i = 0; i < MAX_SHORTHAND_CONFIGS; i++ ) + for( i = 0; i < nr_static_configs; i++ ) { config = &static_configs[i]; - if( !config->name || strcmp( config->name, name ) == 0 ) break; + if( strcmp( config->name, name ) == 0 ) break; } + config = &static_configs[i]; if( i == MAX_SHORTHAND_CONFIGS ) { fprintf( stderr, "Fatal: Too many static configuration items. Please recompile with a higher MAX_STATIC_CONFIGS\n" ); exit( -1 ); } + if( i == nr_static_configs ) nr_static_configs++; + if( !config->description ) config->description = description; if( !config->name ) config->name = name; if( config->type && config->type != vt ) { - fprintf( stderr, "Fatal: Internal error on variable %s. Types disagree.\n", name ); + fprintf( stderr, "Fatal: Internal error on variable %s. Types disagree [%c/%c].\n", name, config->type, vt ); exit( -2 ); } config->type = vt; @@ -61,50 +65,113 @@ void survive_config_bind_variable( char vt, int * variable, const char * name, c default: fprintf( stderr, "Fatal: Internal error on variable %s. Unknown type %c\n", name, vt ); } - *variable = i; } -void survive_config_populate_ctx( SurviveContext * ctx ) +int survive_print_help_for_parameter( const char * tomap ) { int i; - struct static_conf_t * config; - for( i = 0; i < MAX_SHORTHAND_CONFIGS; i++ ) + for( i = 0; i < nr_static_configs; i++ ) { - config = &static_configs[i]; - switch( config->type ) + struct static_conf_t * sc = &static_configs[i]; + if( strcmp( sc->name, tomap ) == 0 ) { - case 'i': ctx->shorthand_configs[i].i = config->data_default.i; - case 'f': ctx->shorthand_configs[i].f = config->data_default.f; - case 's': ctx->shorthand_configs[i].s = config->data_default.s; + char sthelp[160]; + snprintf( sthelp, 159, " %s: %s [%c]", sc->name, sc->description, sc->type ); + fprintf( stderr, "\0337\033[1A\033[1000D%s\0338", sthelp, strlen( sthelp )); + return 1; } } + return 0; } -void survive_print_known_configs( SurviveContext * ctx ) +static void PrintConfigGroup(config_group * grp, const char ** chkval, int * cvs, int verbose ) { - int i; - struct static_conf_t * config; - for( i = 0; i < MAX_SHORTHAND_CONFIGS; i++ ) + int i, j; + for( i = 0; i < grp->used_entries; i++ ) { - config = &static_configs[i]; - if( !config->name ) break; - switch( config->type ) + config_entry * ce = &grp->config_entries[i]; + for( j = 0; j < *cvs; j++ ) + { + if( strcmp( chkval[j], ce->tag ) == 0 ) break; + } + if( j == *cvs ) { - case 'i': printf( "%10d %20s %s\n", config->data_default.i, config->name, config->description ); break; - case 'f': printf( "%10f %20s %s\n", config->data_default.f, config->name, config->description ); break; - case 's': printf( "%10s %20s %s\n", config->data_default.s, config->name, config->description ); break; + if( verbose ) + { + char stobuf[128]; + switch( ce->type ) + { + case CONFIG_UINT32: snprintf( stobuf, 127, " --%s %d", ce->tag, ce->numeric.i ); break; + case CONFIG_FLOAT: snprintf( stobuf, 127, " --%s %f", ce->tag, ce->numeric.f ); break; + case CONFIG_STRING: snprintf( stobuf, 127, " --%s %s", ce->tag, ce->data ); break; + case CONFIG_FLOAT_ARRAY: printf( "[FA] %20s", ce->tag ); break; + } + + int namepad = 40 - strlen( stobuf ); + printf( "%s%*c", stobuf, namepad, (ce->type==CONFIG_FLOAT)?'f':(ce->type==CONFIG_UINT32)?'i':(ce->type==CONFIG_STRING)?'s':'.' ); + + //Try to get description from the static tags. + for( j = 0; j < nr_static_configs; j++ ) + { + if( strcmp( static_configs[j].name, ce->tag ) == 0 ) + { + printf( " %s", static_configs[j].description ); + } + } + printf( "\n" ); + } + else + { + printf( "--%s ", ce->tag ); + } + chkval[*cvs] = ce->tag; + (*cvs)++; } } - - //XXX TODO: Maybe this should print out the actual config values after being updated from the rest of the config system? - //struct config_group *global_config_values; - //struct config_group *temporary_config_values; // Set per-session, from command-line. Not saved but override global_config_values } +void survive_print_known_configs( SurviveContext * ctx, int verbose ) +{ + int i; - - - + const char * checked_values[256]; + int cvs = 0; + memset( checked_values, 0, sizeof( checked_values ) ); + PrintConfigGroup( ctx->temporary_config_values, checked_values, &cvs, verbose ); + PrintConfigGroup( ctx->global_config_values, checked_values, &cvs, verbose ); + int j; + for( j = 0; j < nr_static_configs; j++ ) + { + for( i = 0; i < cvs; i++ ) + { + if( strcmp( static_configs[j].name, checked_values[i] ) == 0 ) + break; + } + if( i == cvs ) + { + struct static_conf_t * config = &static_configs[j]; + const char * name = config->name; + + if( verbose ) + { + char stobuf[128]; + switch( config->type ) + { + case 'i': snprintf( stobuf, 127, " --%s %d", name, config->data_default.i ); break; + case 'f': snprintf( stobuf, 127, " --%s %f", name, config->data_default.f ); break; + case 's': snprintf( stobuf, 127, " --%s %s", name, config->data_default.s ); break; + case 'a': snprintf( stobuf, 127, "[FA] %25s %s\n", config->name, config->description ); break; + } + int namepad = 40 - strlen( stobuf ); + printf( "%s%*c %s\n", stobuf, namepad, config->type, config->description ); + } + else + { + printf( "--%s ", name ); + } + } + } +} const FLT *config_set_float_a(config_group *cg, const char *tag, const FLT *values, uint8_t count); @@ -113,7 +180,7 @@ void init_config_entry(config_entry *ce) { ce->tag = NULL; ce->type = CONFIG_UNKNOWN; ce->elements = 0; - ce->shorthand_place = -1; + ce->update_list = 0; } void destroy_config_entry(config_entry *ce) { @@ -313,20 +380,6 @@ config_entry *next_unused_entry(config_group *cg, const char * tag) { cg->used_entries++; - - int i; - struct static_conf_t * config; - for( i = 0; i < MAX_SHORTHAND_CONFIGS; i++ ) - { - config = &static_configs[i]; - if( !config->name ) break; - if( strcmp( config->name, tag ) == 0 ) - { - cv->shorthand_place = i; - break; - } - } - return cv; } @@ -344,7 +397,8 @@ const char *config_set_str(config_group *cg, const char *tag, const char *value) } cv->type = CONFIG_STRING; - if( cv->shorthand_place >= 0 ) cg->ctx->shorthand_configs[cv->shorthand_place].s = value; + update_list_t * t = cv->update_list; + while( t ) { *((const char **)t->value) = value; t = t->next; } return value; } @@ -358,7 +412,8 @@ const uint32_t config_set_uint32(config_group *cg, const char *tag, const uint32 cv->numeric.i = value; cv->type = CONFIG_UINT32; - if( cv->shorthand_place >= 0 ) cg->ctx->shorthand_configs[cv->shorthand_place].i = value; + update_list_t * t = cv->update_list; + while( t ) { *((uint32_t*)t->value) = value; t = t->next; } return value; } @@ -372,7 +427,9 @@ const FLT config_set_float(config_group *cg, const char *tag, const FLT value) { cv->numeric.f = value; cv->type = CONFIG_FLOAT; - if( cv->shorthand_place >= 0 ) cg->ctx->shorthand_configs[cv->shorthand_place].f = value; + + update_list_t * t = cv->update_list; + while( t ) { *((FLT*)t->value) = value; t = t->next; } return value; } @@ -610,6 +667,21 @@ FLT survive_configf(SurviveContext *ctx, const char *tag, char flags, FLT def) { } } + + int i; + if( !(flags & SC_OVERRIDE) ) + { + for( i = 0; i < nr_static_configs; i++ ) + { + struct static_conf_t * sc = &static_configs[i]; + if( strcmp( tag, sc->name ) == 0 ) + { + def = sc->data_default.f; + } + } + } + + // If override is flagged, or, we can't find the variable, ,continue on. if (flags & SC_SETCONFIG) { config_set_float(ctx->temporary_config_values, tag, def); @@ -629,6 +701,21 @@ uint32_t survive_configi(SurviveContext *ctx, const char *tag, char flags, uint3 } } + uint32_t statictimedef = def; + int i; + if( !(flags & SC_OVERRIDE) ) + { + for( i = 0; i < nr_static_configs; i++ ) + { + struct static_conf_t * sc = &static_configs[i]; + if( strcmp( tag, sc->name ) == 0 ) + { + def = sc->data_default.i; + } + } + } + + // If override is flagged, or, we can't find the variable, ,continue on. if (flags & SC_SETCONFIG) { config_set_uint32(ctx->temporary_config_values, tag, def); @@ -647,15 +734,87 @@ const char *survive_configs(SurviveContext *ctx, const char *tag, char flags, co return cv->data; } - // If override is flagged, or, we can't find the variable, ,continue on. - if (flags & SC_SETCONFIG) { - config_set_str(ctx->temporary_config_values, tag, def); - config_set_str(ctx->global_config_values, tag, def); - } else if (flags & SC_SET) { - config_set_str(ctx->temporary_config_values, tag, def); + int i; + char foundtype = 0; + const char * founddata = def; + for( i = 0; i < nr_static_configs; i++ ) + { + struct static_conf_t * sc = &static_configs[i]; + if( !sc ) break; + if( strcmp( tag, sc->name ) == 0 ) + { + founddata = sc->data_default.s; + foundtype = sc->type; + if( !(flags & SC_OVERRIDE) ) + { + def = founddata; + } + } + } + + if( !foundtype || foundtype == 's' ) + { + // If override is flagged, or, we can't find the variable, ,continue on. + if (flags & SC_SETCONFIG) { + config_set_str(ctx->temporary_config_values, tag, def); + config_set_str(ctx->global_config_values, tag, def); + } else if (flags & SC_SET) { + config_set_str(ctx->temporary_config_values, tag, def); + } else { + return founddata; + } + } + else if( foundtype == 'i' ) + { + survive_configi( ctx, tag, flags, atoi( def ) ); + } + else if( foundtype == 'f' ) + { + survive_configf( ctx, tag, flags, atof( def ) ); } return def; } +SURVIVE_EXPORT void survive_attach_config(SurviveContext *ctx, const char *tag, void * var, char type ) +{ + config_entry *cv = sc_search(ctx, tag); + if( !cv ) + { + SV_ERROR( "Configuration item %s not initialized.\n", tag ); + return; + } + update_list_t ** ul = &cv->update_list; + while( *ul ) + { + if( (*ul)->value == var ) return; + ul = &((*ul)->next); + } + update_list_t * t = *ul = malloc( sizeof( update_list_t ) ); + t->next = 0; + t->value = var; +} + +SURVIVE_EXPORT void survive_detach_config(SurviveContext *ctx, const char *tag, void * var ) +{ + config_entry *cv = sc_search(ctx, tag); + if( !cv ) + { + SV_ERROR( "Configuration item %s not initialized.\n", tag ); + return; + } + + update_list_t ** ul = &cv->update_list; + while( *ul ) + { + if( (*ul)->value == var ) + { + update_list_t * v = *ul; + *ul = (*ul)->next; + free( v ); + } + ul = &((*ul)->next); + } +} + -- cgit v1.2.3