diff options
author | Michael Brown | 2008-03-18 16:51:03 +0100 |
---|---|---|
committer | Michael Brown | 2008-03-18 16:51:03 +0100 |
commit | af1c6b869c10afdf9fa7dd3e4d5dbd9330cef7dc (patch) | |
tree | 6ba6a87eeca4741f9079b7d6dade8b4870a0489e /src/core/settings.c | |
parent | [Timers] Initialise timers on first use (diff) | |
download | ipxe-af1c6b869c10afdf9fa7dd3e4d5dbd9330cef7dc.tar.gz ipxe-af1c6b869c10afdf9fa7dd3e4d5dbd9330cef7dc.tar.xz ipxe-af1c6b869c10afdf9fa7dd3e4d5dbd9330cef7dc.zip |
[Settings] Allow named settings to have their type specified explicitly
Allow setting names such as "ip:hex".
Diffstat (limited to 'src/core/settings.c')
-rw-r--r-- | src/core/settings.c | 93 |
1 files changed, 48 insertions, 45 deletions
diff --git a/src/core/settings.c b/src/core/settings.c index 42de5c4e..1cf711d2 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -87,49 +87,54 @@ static struct config_setting * find_config_setting ( const char *name ) { * Find or build configuration setting * * @v name Name - * @v tmp_setting Temporary buffer for constructing a setting - * @ret setting Configuration setting, or NULL + * @v setting Buffer to fill in with setting + * @ret rc Return status code * * Find setting if it exists. If it doesn't exist, but the name is of * the form "<num>:<type>" (e.g. "12:string"), then construct a * setting for that tag and data type, and return it. The constructed - * setting will be placed in the temporary buffer. + * setting will be placed in the buffer. */ -static struct config_setting * -find_or_build_config_setting ( const char *name, - struct config_setting *tmp_setting ) { - struct config_setting *setting; - char *separator; - - /* Look in the list of registered settings first */ - setting = find_config_setting ( name ); - if ( setting ) - return setting; - - /* If name is of the form "<num>:<type>", try to construct a setting */ - setting = tmp_setting; +static int find_or_build_config_setting ( const char *name, + struct config_setting *setting ) { + struct config_setting *known_setting; + char tmp_name[ strlen ( name ) + 1 ]; + char *qualifier; + char *tmp; + + /* Set defaults */ memset ( setting, 0, sizeof ( *setting ) ); setting->name = name; - for ( separator = ( char * ) name ; 1 ; separator++ ) { - setting->tag = ( ( setting->tag << 8 ) | - strtoul ( separator, &separator, 0 ) ); - if ( *separator != '.' ) - break; + setting->type = &config_setting_type_hex; + + /* Strip qualifier, if present */ + memcpy ( tmp_name, name, sizeof ( tmp_name ) ); + if ( ( qualifier = strchr ( tmp_name, ':' ) ) != NULL ) + *(qualifier++) = 0; + + /* If we recognise the name of the setting, use it */ + if ( ( known_setting = find_config_setting ( tmp_name ) ) != NULL ) { + memcpy ( setting, known_setting, sizeof ( *setting ) ); + } else { + /* Otherwise, try to interpret as a numerical setting */ + for ( tmp = tmp_name ; 1 ; tmp++ ) { + setting->tag = ( ( setting->tag << 8 ) | + strtoul ( tmp, &tmp, 0 ) ); + if ( *tmp != '.' ) + break; + } + if ( *tmp != 0 ) + return -EINVAL; } - switch ( *separator ) { - case ':' : - setting->type = find_config_setting_type ( separator + 1 ); - break; - case '\0' : - setting->type = &config_setting_type_hex; - break; - default : - break; + /* Apply qualifier, if present */ + if ( qualifier ) { + setting->type = find_config_setting_type ( qualifier ); + if ( ! setting->type ) + return -EINVAL; } - if ( ! setting->type ) - return NULL; - return setting; + + return 0; } /** @@ -143,13 +148,12 @@ find_or_build_config_setting ( const char *name, */ int show_named_setting ( struct config_context *context, const char *name, char *buf, size_t len ) { - struct config_setting *setting; - struct config_setting tmp_setting; + struct config_setting setting; + int rc; - setting = find_or_build_config_setting ( name, &tmp_setting ); - if ( ! setting ) - return -ENOENT; - return show_setting ( context, setting, buf, len ); + if ( ( rc = find_or_build_config_setting ( name, &setting ) ) != 0 ) + return rc; + return show_setting ( context, &setting, buf, len ); } /** @@ -162,13 +166,12 @@ int show_named_setting ( struct config_context *context, const char *name, */ int set_named_setting ( struct config_context *context, const char *name, const char *value ) { - struct config_setting *setting; - struct config_setting tmp_setting; + struct config_setting setting; + int rc; - setting = find_or_build_config_setting ( name, &tmp_setting ); - if ( ! setting ) - return -ENOENT; - return setting->type->set ( context, setting, value ); + if ( ( rc = find_or_build_config_setting ( name, &setting ) ) != 0 ) + return rc; + return set_setting ( context, &setting, value ); } /** |