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 );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
@ -580,7 +605,7 @@ int store_setting ( struct settings *settings, const struct setting *setting,
|
|||
/* Find target settings block */
|
||||
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 ) )
|
||||
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,
|
||||
struct settings **origin, struct setting *fetched,
|
||||
void *data, size_t len ) {
|
||||
const struct setting *applicable;
|
||||
struct settings *child;
|
||||
struct setting tmp;
|
||||
int ret;
|
||||
|
@ -646,11 +672,11 @@ int fetch_setting ( struct settings *settings, const struct setting *setting,
|
|||
if ( ! settings->op->fetch )
|
||||
return -ENOTSUP;
|
||||
|
||||
/* Try this block first, if applicable */
|
||||
if ( setting_applies ( settings, setting ) ) {
|
||||
/* Try this block first, if an applicable setting exists */
|
||||
if ( ( applicable = applicable_setting ( settings, setting ) ) ) {
|
||||
|
||||
/* Create modifiable copy of setting */
|
||||
memcpy ( &tmp, setting, sizeof ( tmp ) );
|
||||
memcpy ( &tmp, applicable, sizeof ( tmp ) );
|
||||
if ( ( ret = settings->op->fetch ( settings, &tmp,
|
||||
data, len ) ) >= 0 ) {
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ static unsigned int select_setting_row ( struct setting_widget *widget,
|
|||
unsigned int index ) {
|
||||
struct settings *settings;
|
||||
struct setting *setting;
|
||||
struct setting *previous = NULL;
|
||||
unsigned int count = 0;
|
||||
|
||||
/* Initialise structure */
|
||||
|
@ -146,11 +147,18 @@ static unsigned int select_setting_row ( struct setting_widget *widget,
|
|||
|
||||
/* Include any applicable settings */
|
||||
for_each_table_entry ( setting, SETTINGS ) {
|
||||
|
||||
/* Skip inapplicable settings */
|
||||
if ( ! setting_applies ( widget->settings, setting ) )
|
||||
continue;
|
||||
if ( count++ == index ) {
|
||||
|
||||
/* Read current setting value and origin */
|
||||
/* Skip duplicate settings */
|
||||
if ( previous && ( setting_cmp ( setting, previous ) == 0 ) )
|
||||
continue;
|
||||
previous = setting;
|
||||
|
||||
/* Read current setting value and origin */
|
||||
if ( count++ == index ) {
|
||||
fetchf_setting ( widget->settings, setting,
|
||||
&widget->row.origin,
|
||||
&widget->row.setting,
|
||||
|
|
|
@ -126,6 +126,7 @@ static void efi_snp_hii_questions ( struct efi_snp_device *snpdev,
|
|||
struct efi_ifr_builder *ifr,
|
||||
unsigned int varstore_id ) {
|
||||
struct setting *setting;
|
||||
struct setting *previous = NULL;
|
||||
unsigned int name_id;
|
||||
unsigned int prompt_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 ) {
|
||||
if ( ! efi_snp_hii_setting_applies ( snpdev, setting ) )
|
||||
continue;
|
||||
if ( previous && ( setting_cmp ( setting, previous ) == 0 ) )
|
||||
continue;
|
||||
previous = setting;
|
||||
name_id = efi_ifr_string ( ifr, "%s", setting->name );
|
||||
prompt_id = efi_ifr_string ( ifr, "%s", setting->description );
|
||||
help_id = efi_ifr_string ( ifr, "http://ipxe.org/cfg/%s",
|
||||
|
|
Loading…
Reference in New Issue