From 25ec56e0ecaa516a790fc409798e031af4bba650 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 31 Aug 2012 03:52:06 +0100 Subject: [PATCH] [settings] Use a generic setting's own type as its default type When fetching a named setting using a name that does not explicitly specify a type, default to using the type stored when the setting was created, rather than always defaulting to "string". This allows the behaviour of user-defined settings to match the behaviour of predefined settings (which have a sensible default type). For example: set server:ipv4 192.168.0.1 echo ${server} will now print "192.168.0.1", rather than trying to print out the raw IPv4 address bytes as a string. The downside of this change is that existing tricks for printing special characters within scripts may require (backwards-compatible) modification. For example, the "clear screen" sequence: set esc:hex 1b set cls ${esc}[2J echo ${cls} will now have to become set esc:hex 1b set cls ${esc:string}[2J # Must now explicitly specify ":string" echo ${cls} Signed-off-by: Michael Brown --- src/core/settings.c | 57 ++++++++++++++++++++++++++++++++----- src/hci/commands/menu_cmd.c | 3 +- src/hci/commands/nvo_cmd.c | 3 +- src/include/ipxe/settings.h | 9 ++++-- 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/core/settings.c b/src/core/settings.c index 392f598d..20b7f949 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -180,6 +180,11 @@ int generic_settings_fetch ( struct settings *settings, if ( len > generic->data_len ) len = generic->data_len; memcpy ( data, generic_setting_data ( generic ), len ); + + /* Set setting type, if not yet specified */ + if ( ! setting->type ) + setting->type = generic->setting.type; + return generic->data_len; } @@ -614,8 +619,12 @@ static int fetch_setting_and_origin ( struct settings *settings, if ( setting_applies ( settings, setting ) && ( ( ret = settings->op->fetch ( settings, setting, data, len ) ) >= 0 ) ) { + /* Record origin, if applicable */ if ( origin ) *origin = settings; + /* Default to string setting type, if not yet specified */ + if ( ! setting->type ) + setting->type = &setting_type_string; return ret; } @@ -1132,6 +1141,7 @@ static struct setting_type * find_setting_type ( const char *name ) { * @v get_child Function to find or create child settings block * @v settings Settings block to fill in * @v setting Setting to fill in + * @v default_type Default type to use, if none specified * @v tmp_name Buffer for copy of setting name * @ret rc Return status code * @@ -1147,6 +1157,7 @@ parse_setting_name ( const char *name, struct settings * ( * get_child ) ( struct settings *, const char * ), struct settings **settings, struct setting *setting, + struct setting_type *default_type, char *tmp_name ) { char *settings_name; char *setting_name; @@ -1157,7 +1168,7 @@ parse_setting_name ( const char *name, *settings = &settings_root; memset ( setting, 0, sizeof ( *setting ) ); setting->name = ""; - setting->type = &setting_type_string; + setting->type = default_type; /* Split name into "[settings_name/]setting_name[:type_name]" */ strcpy ( tmp_name, name ); @@ -1227,13 +1238,16 @@ int setting_name ( struct settings *settings, struct setting *setting, } /** - * Parse and store value of named setting + * Store value of named setting * * @v name Name of setting - * @v value Formatted setting data, or NULL + * @v default_type Default type to use, if none specified + * @v data Setting data, or NULL to clear setting + * @v len Length of setting data * @ret rc Return status code */ -int storef_named_setting ( const char *name, const char *value ) { +int store_named_setting ( const char *name, struct setting_type *default_type, + const void *data, size_t len ) { struct settings *settings; struct setting setting; char tmp_name[ strlen ( name ) + 1 ]; @@ -1241,7 +1255,36 @@ int storef_named_setting ( const char *name, const char *value ) { /* Parse setting name */ if ( ( rc = parse_setting_name ( name, autovivify_child_settings, - &settings, &setting, tmp_name )) != 0) + &settings, &setting, default_type, + tmp_name ) ) != 0 ) + return rc; + + /* Store setting */ + if ( ( rc = store_setting ( settings, &setting, data, len ) ) != 0 ) + return rc; + + return 0; +} + +/** + * Parse and store value of named setting + * + * @v name Name of setting + * @v default_type Default type to use, if none specified + * @v value Formatted setting data, or NULL + * @ret rc Return status code + */ +int storef_named_setting ( const char *name, struct setting_type *default_type, + const char *value ) { + struct settings *settings; + struct setting setting; + char tmp_name[ strlen ( name ) + 1 ]; + int rc; + + /* Parse setting name */ + if ( ( rc = parse_setting_name ( name, autovivify_child_settings, + &settings, &setting, default_type, + tmp_name ) ) != 0 ) return rc; /* Store setting */ @@ -1272,8 +1315,8 @@ int fetchf_named_setting ( const char *name, int rc; /* Parse setting name */ - if ( ( rc = parse_setting_name ( name, find_child_settings, - &settings, &setting, tmp_name )) != 0) + if ( ( rc = parse_setting_name ( name, find_child_settings, &settings, + &setting, NULL, tmp_name ) ) != 0 ) return rc; /* Fetch setting */ diff --git a/src/hci/commands/menu_cmd.c b/src/hci/commands/menu_cmd.c index c11baea7..10966db2 100644 --- a/src/hci/commands/menu_cmd.c +++ b/src/hci/commands/menu_cmd.c @@ -249,7 +249,8 @@ static int choose_exec ( int argc, char **argv ) { goto err_show_menu; /* Store setting */ - if ( ( rc = storef_named_setting ( setting, item->label ) ) != 0 ) { + if ( ( rc = storef_named_setting ( setting, &setting_type_string, + item->label ) ) != 0 ) { printf ( "Could not store \"%s\": %s\n", setting, strerror ( rc ) ); goto err_store; diff --git a/src/hci/commands/nvo_cmd.c b/src/hci/commands/nvo_cmd.c index 4bb7f457..fb8ec876 100644 --- a/src/hci/commands/nvo_cmd.c +++ b/src/hci/commands/nvo_cmd.c @@ -127,7 +127,8 @@ static int set_core_exec ( int argc, char **argv, goto err_get_value; /* Determine total length of command line */ - if ( ( rc = storef_named_setting ( name, value ) ) != 0 ) { + if ( ( rc = storef_named_setting ( name, &setting_type_string, + value ) ) != 0 ) { printf ( "Could not %s \"%s\": %s\n", argv[0], name, strerror ( rc ) ); goto err_store; diff --git a/src/include/ipxe/settings.h b/src/include/ipxe/settings.h index cd446202..a81e5ccf 100644 --- a/src/include/ipxe/settings.h +++ b/src/include/ipxe/settings.h @@ -280,7 +280,12 @@ extern int fetchf_setting ( struct settings *settings, struct setting *setting, extern int storef_setting ( struct settings *settings, struct setting *setting, const char *value ); -extern int storef_named_setting ( const char *name, const char *value ); +extern int store_named_setting ( const char *name, + struct setting_type *default_type, + const void *data, size_t len ); +extern int storef_named_setting ( const char *name, + struct setting_type *default_type, + const char *value ); extern int fetchf_named_setting ( const char *name, char *name_buf, size_t name_len, char *value_buf, size_t value_len ); @@ -366,7 +371,7 @@ static inline int delete_setting ( struct settings *settings, * @ret rc Return status code */ static inline int delete_named_setting ( const char *name ) { - return storef_named_setting ( name, NULL ); + return store_named_setting ( name, NULL, NULL, 0 ); } /**