Skip to content

Commit

Permalink
[settings] Use a generic setting's own type as its default type
Browse files Browse the repository at this point in the history
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 <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Sep 10, 2012
1 parent e6427b7 commit 25ec56e
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 9 deletions.
53 changes: 48 additions & 5 deletions src/core/settings.c
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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
*
Expand All @@ -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;
Expand All @@ -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 );
Expand Down Expand Up @@ -1226,22 +1237,54 @@ int setting_name ( struct settings *settings, struct setting *setting,
setting->name, setting->type->name );
}

/**
* Store value of named setting
*
* @v name Name of setting
* @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 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 ];
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 */
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, const char *value ) {
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, tmp_name )) != 0)
&settings, &setting, default_type,
tmp_name ) ) != 0 )
return rc;

/* Store setting */
Expand Down Expand Up @@ -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 */
Expand Down
3 changes: 2 additions & 1 deletion src/hci/commands/menu_cmd.c
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion src/hci/commands/nvo_cmd.c
Expand Up @@ -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;
Expand Down
9 changes: 7 additions & 2 deletions src/include/ipxe/settings.h
Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
}

/**
Expand Down

0 comments on commit 25ec56e

Please sign in to comment.