]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[settings] Allow for multiple definitions of each predefined setting
authorMichael Brown <mcb30@ipxe.org>
Tue, 19 Nov 2013 15:34:58 +0000 (15:34 +0000)
committerMichael Brown <mcb30@ipxe.org>
Thu, 5 Dec 2013 12:43:28 +0000 (12:43 +0000)
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>
src/core/settings.c
src/hci/tui/settings_ui.c
src/interface/efi/efi_snp_hii.c

index 8ce2af2b3200881cc051309f083260d6e7bae30c..1f99bca895536cd8cd12457896f6883e2aa5ef70 100644 (file)
@@ -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 ) {
 
index 8fe13ad8b8e0c7fde407e8148011786419de24b3..87afc9ba2a9e6496f89ecd4091ea792db7b9cb33 100644 (file)
@@ -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,
index 61954b63270e01cbfba31cf816516b0792edecb8..c272527c0611efd68cdcb38ffef899b39b15fcd1 100644 (file)
@@ -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",