mirror of https://github.com/ipxe/ipxe.git
[settings] Allow for multiple definitions of each predefined setting
Allow for multiple setting definitions with the same name but different scopes and tags. For example, allow for a "filename" setting with default scope and tag value 67 (for DHCPv4) and a corresponding "filename" setting with IPv6 scope and tag value 59 (for DHCPv6). Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/17/head
parent
b0942534eb
commit
eaa8615648
|
@ -564,6 +564,31 @@ int setting_applies ( struct settings *settings,
|
||||||
settings->op->applies ( settings, setting ) : 1 );
|
settings->op->applies ( settings, setting ) : 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find setting applicable to settings block, if any
|
||||||
|
*
|
||||||
|
* @v settings Settings block
|
||||||
|
* @v setting Setting
|
||||||
|
* @ret setting Applicable setting, if any
|
||||||
|
*/
|
||||||
|
static const struct setting *
|
||||||
|
applicable_setting ( struct settings *settings, const struct setting *setting ){
|
||||||
|
const struct setting *applicable;
|
||||||
|
|
||||||
|
/* If setting is already applicable, use it */
|
||||||
|
if ( setting_applies ( settings, setting ) )
|
||||||
|
return setting;
|
||||||
|
|
||||||
|
/* Otherwise, look for a matching predefined setting which does apply */
|
||||||
|
for_each_table_entry ( applicable, SETTINGS ) {
|
||||||
|
if ( ( setting_cmp ( setting, applicable ) == 0 ) &&
|
||||||
|
( setting_applies ( settings, applicable ) ) )
|
||||||
|
return applicable;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store value of setting
|
* Store value of setting
|
||||||
*
|
*
|
||||||
|
@ -580,7 +605,7 @@ int store_setting ( struct settings *settings, const struct setting *setting,
|
||||||
/* Find target settings block */
|
/* Find target settings block */
|
||||||
settings = settings_target ( settings );
|
settings = settings_target ( settings );
|
||||||
|
|
||||||
/* Fail if tag does not apply to this settings block */
|
/* Fail if setting does not apply to this settings block */
|
||||||
if ( ! setting_applies ( settings, setting ) )
|
if ( ! setting_applies ( settings, setting ) )
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
|
||||||
|
@ -628,6 +653,7 @@ int store_setting ( struct settings *settings, const struct setting *setting,
|
||||||
int fetch_setting ( struct settings *settings, const struct setting *setting,
|
int fetch_setting ( struct settings *settings, const struct setting *setting,
|
||||||
struct settings **origin, struct setting *fetched,
|
struct settings **origin, struct setting *fetched,
|
||||||
void *data, size_t len ) {
|
void *data, size_t len ) {
|
||||||
|
const struct setting *applicable;
|
||||||
struct settings *child;
|
struct settings *child;
|
||||||
struct setting tmp;
|
struct setting tmp;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -646,11 +672,11 @@ int fetch_setting ( struct settings *settings, const struct setting *setting,
|
||||||
if ( ! settings->op->fetch )
|
if ( ! settings->op->fetch )
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
|
||||||
/* Try this block first, if applicable */
|
/* Try this block first, if an applicable setting exists */
|
||||||
if ( setting_applies ( settings, setting ) ) {
|
if ( ( applicable = applicable_setting ( settings, setting ) ) ) {
|
||||||
|
|
||||||
/* Create modifiable copy of setting */
|
/* Create modifiable copy of setting */
|
||||||
memcpy ( &tmp, setting, sizeof ( tmp ) );
|
memcpy ( &tmp, applicable, sizeof ( tmp ) );
|
||||||
if ( ( ret = settings->op->fetch ( settings, &tmp,
|
if ( ( ret = settings->op->fetch ( settings, &tmp,
|
||||||
data, len ) ) >= 0 ) {
|
data, len ) ) >= 0 ) {
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,7 @@ static unsigned int select_setting_row ( struct setting_widget *widget,
|
||||||
unsigned int index ) {
|
unsigned int index ) {
|
||||||
struct settings *settings;
|
struct settings *settings;
|
||||||
struct setting *setting;
|
struct setting *setting;
|
||||||
|
struct setting *previous = NULL;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
/* Initialise structure */
|
/* Initialise structure */
|
||||||
|
@ -146,11 +147,18 @@ static unsigned int select_setting_row ( struct setting_widget *widget,
|
||||||
|
|
||||||
/* Include any applicable settings */
|
/* Include any applicable settings */
|
||||||
for_each_table_entry ( setting, SETTINGS ) {
|
for_each_table_entry ( setting, SETTINGS ) {
|
||||||
|
|
||||||
|
/* Skip inapplicable settings */
|
||||||
if ( ! setting_applies ( widget->settings, setting ) )
|
if ( ! setting_applies ( widget->settings, setting ) )
|
||||||
continue;
|
continue;
|
||||||
if ( count++ == index ) {
|
|
||||||
|
/* Skip duplicate settings */
|
||||||
|
if ( previous && ( setting_cmp ( setting, previous ) == 0 ) )
|
||||||
|
continue;
|
||||||
|
previous = setting;
|
||||||
|
|
||||||
/* Read current setting value and origin */
|
/* Read current setting value and origin */
|
||||||
|
if ( count++ == index ) {
|
||||||
fetchf_setting ( widget->settings, setting,
|
fetchf_setting ( widget->settings, setting,
|
||||||
&widget->row.origin,
|
&widget->row.origin,
|
||||||
&widget->row.setting,
|
&widget->row.setting,
|
||||||
|
|
|
@ -126,6 +126,7 @@ static void efi_snp_hii_questions ( struct efi_snp_device *snpdev,
|
||||||
struct efi_ifr_builder *ifr,
|
struct efi_ifr_builder *ifr,
|
||||||
unsigned int varstore_id ) {
|
unsigned int varstore_id ) {
|
||||||
struct setting *setting;
|
struct setting *setting;
|
||||||
|
struct setting *previous = NULL;
|
||||||
unsigned int name_id;
|
unsigned int name_id;
|
||||||
unsigned int prompt_id;
|
unsigned int prompt_id;
|
||||||
unsigned int help_id;
|
unsigned int help_id;
|
||||||
|
@ -135,6 +136,9 @@ static void efi_snp_hii_questions ( struct efi_snp_device *snpdev,
|
||||||
for_each_table_entry ( setting, SETTINGS ) {
|
for_each_table_entry ( setting, SETTINGS ) {
|
||||||
if ( ! efi_snp_hii_setting_applies ( snpdev, setting ) )
|
if ( ! efi_snp_hii_setting_applies ( snpdev, setting ) )
|
||||||
continue;
|
continue;
|
||||||
|
if ( previous && ( setting_cmp ( setting, previous ) == 0 ) )
|
||||||
|
continue;
|
||||||
|
previous = setting;
|
||||||
name_id = efi_ifr_string ( ifr, "%s", setting->name );
|
name_id = efi_ifr_string ( ifr, "%s", setting->name );
|
||||||
prompt_id = efi_ifr_string ( ifr, "%s", setting->description );
|
prompt_id = efi_ifr_string ( ifr, "%s", setting->description );
|
||||||
help_id = efi_ifr_string ( ifr, "http://ipxe.org/cfg/%s",
|
help_id = efi_ifr_string ( ifr, "http://ipxe.org/cfg/%s",
|
||||||
|
|
Loading…
Reference in New Issue