diff options
author | Michael Brown | 2011-03-22 18:41:47 +0100 |
---|---|---|
committer | Michael Brown | 2011-03-22 20:55:06 +0100 |
commit | ba8dd804879c1b2e36b414ea6622952836927d45 (patch) | |
tree | 8d4f8e754431718deae61dd467cb672ffb0d1fa0 /src/core/settings.c | |
parent | [settings] Expose settings_name() (diff) | |
download | ipxe-ba8dd804879c1b2e36b414ea6622952836927d45.tar.gz ipxe-ba8dd804879c1b2e36b414ea6622952836927d45.tar.xz ipxe-ba8dd804879c1b2e36b414ea6622952836927d45.zip |
[settings] Provide fetch_setting_origin()
Inspired-by: Glenn Brown <glenn@myri.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core/settings.c')
-rw-r--r-- | src/core/settings.c | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/src/core/settings.c b/src/core/settings.c index 6b3e7411..06d22ed3 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -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,13 +588,15 @@ 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; } @@ -597,6 +604,41 @@ int fetch_setting ( struct settings *settings, struct setting *setting, } /** + * 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 * * @v settings Settings block, or NULL to search all blocks |