]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[settings] Provide fetch_setting_origin()
authorMichael Brown <mcb30@ipxe.org>
Tue, 22 Mar 2011 17:41:47 +0000 (17:41 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 22 Mar 2011 19:55:06 +0000 (19:55 +0000)
Inspired-by: Glenn Brown <glenn@myri.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/core/settings.c
src/include/ipxe/settings.h

index 6b3e74115a72d8d85e69d160bb9920b5e3b09c7e..06d22ed3552606a2116d48a641100f5f7130a0b3 100644 (file)
@@ -552,10 +552,11 @@ int store_setting ( struct settings *settings, struct setting *setting,
 }
 
 /**
- * Fetch value of setting
+ * Fetch value and origin of setting
  *
  * @v settings         Settings block, or NULL to search all blocks
  * @v setting          Setting to fetch
+ * @v origin           Origin of setting to fill in
  * @v data             Buffer to fill with setting data
  * @v len              Length of buffer
  * @ret len            Length of setting data, or negative error
@@ -563,13 +564,17 @@ int store_setting ( struct settings *settings, struct setting *setting,
  * The actual length of the setting will be returned even if
  * the buffer was too small.
  */
-int fetch_setting ( struct settings *settings, struct setting *setting,
-                   void *data, size_t len ) {
+static int fetch_setting_and_origin ( struct settings *settings,
+                                     struct setting *setting,
+                                     struct settings **origin,
+                                     void *data, size_t len ) {
        struct settings *child;
        int ret;
 
        /* Avoid returning uninitialised data on error */
        memset ( data, 0, len );
+       if ( origin )
+               *origin = NULL;
 
        /* NULL settings implies starting at the global settings root */
        if ( ! settings )
@@ -583,19 +588,56 @@ int fetch_setting ( struct settings *settings, struct setting *setting,
        if ( setting_applies ( settings, setting ) &&
             ( ( ret = settings->op->fetch ( settings, setting,
                                             data, len ) ) >= 0 ) ) {
+               if ( origin )
+                       *origin = settings;
                return ret;
        }
 
        /* Recurse into each child block in turn */
        list_for_each_entry ( child, &settings->children, siblings ) {
-               if ( ( ret = fetch_setting ( child, setting,
-                                            data, len ) ) >= 0 )
+               if ( ( ret = fetch_setting_and_origin ( child, setting, origin,
+                                                       data, len ) ) >= 0 )
                        return ret;
        }
 
        return -ENOENT;
 }
 
+/**
+ * Fetch value of setting
+ *
+ * @v settings         Settings block, or NULL to search all blocks
+ * @v setting          Setting to fetch
+ * @v data             Buffer to fill with setting data
+ * @v len              Length of buffer
+ * @ret len            Length of setting data, or negative error
+ *
+ * The actual length of the setting will be returned even if
+ * the buffer was too small.
+ */
+int fetch_setting ( struct settings *settings, struct setting *setting,
+                   void *data, size_t len ) {
+       return fetch_setting_and_origin ( settings, setting, NULL, data, len );
+}
+
+/**
+ * Fetch origin of setting
+ *
+ * @v settings         Settings block, or NULL to search all blocks
+ * @v setting          Setting to fetch
+ * @ret origin         Origin of setting, or NULL if not found
+ *
+ * This function can also be used as an existence check for the
+ * setting.
+ */
+struct settings * fetch_setting_origin ( struct settings *settings,
+                                        struct setting *setting ) {
+       struct settings *origin;
+
+       fetch_setting_and_origin ( settings, setting, &origin, NULL, 0 );
+       return origin;
+}
+
 /**
  * Fetch length of setting
  *
index 5c54168320ddb6d158c152975a746b092039bd46..e132333a7499744a515e84b9e107d03970bceb05 100644 (file)
@@ -217,6 +217,8 @@ extern int store_setting ( struct settings *settings, struct setting *setting,
                           const void *data, size_t len );
 extern int fetch_setting ( struct settings *settings, struct setting *setting,
                           void *data, size_t len );
+extern struct settings * fetch_setting_origin ( struct settings *settings,
+                                               struct setting *setting );
 extern int fetch_setting_len ( struct settings *settings,
                               struct setting *setting );
 extern int fetch_string_setting ( struct settings *settings,