Add generic routine for parsing map-like options on kernel cmd-line This patch adds a generic routine to the kernel, so that a map of settings can be entered on the kernel commandline. Signed-off-by: Remy Bohmer --- --- include/linux/kernel.h | 1 lib/cmdline.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 4 deletions(-) Index: linux-2.6.26/include/linux/kernel.h =================================================================== --- linux-2.6.26.orig/include/linux/kernel.h 2009-03-10 22:35:50.000000000 +0100 +++ linux-2.6.26/include/linux/kernel.h 2009-03-10 22:42:36.000000000 +0100 @@ -174,6 +174,7 @@ extern int vsscanf(const char *, const c extern int get_option(char **str, int *pint); extern char *get_options(const char *str, int nints, int *ints); +extern int get_map_option(const char *str, const char *key, int *pint); extern unsigned long long memparse(char *ptr, char **retptr); extern int core_kernel_text(unsigned long addr); Index: linux-2.6.26/lib/cmdline.c =================================================================== --- linux-2.6.26.orig/lib/cmdline.c 2008-07-13 23:51:29.000000000 +0200 +++ linux-2.6.26/lib/cmdline.c 2009-03-10 22:42:36.000000000 +0100 @@ -15,6 +15,7 @@ #include #include #include +#include /* * If a hyphen was found in get_option, this will handle the @@ -67,6 +68,7 @@ int get_option (char **str, int *pint) return 1; } +EXPORT_SYMBOL(get_option); /** * get_options - Parse a string into a list of integers @@ -112,6 +114,78 @@ char *get_options(const char *str, int n ints[0] = i - 1; return (char *)str; } +EXPORT_SYMBOL(get_options); + +static int +parse_map_field(const char *key, const char *substr, int len, int *pint) +{ + int found = 0; + + if (len != 0) { + if (key) { + /* check if the first part of the key matches */ + if (!strncmp(substr, key, strlen(key))) { + const char *strval = substr + strlen(key); + /* Now the next char must be a ':', + if not, search for the next match */ + if (*strval == ':') { + strval++; + if ((len - (strval - substr)) > 0) { + *pint = (int) + simple_strtol(strval, + NULL, 10); + found = 1; + } + } + } + } else { + /* Check for the absence of any ':' */ + if (strnchr(substr, len, ':') == NULL) { + *pint = (int) simple_strtol(substr, NULL, 10); + found = 1; + } + } + } + + return found; +} + +/** + * get_map_option - Parse integer from an option map + * @str: option string + * @key: The key inside the map, can be NULL + * @pint: (output) integer value parsed from the map @str + * + * This function parses an integer from an option map like + * some_map=key1:99,key2:98,...,keyN:NN,NN + * Only the value of the first match is returned, or if no + * key option is given (key = NULL) the value of the first + * field without a ':' is returned. + * + * Return values: + * 0 - key (or default) not found or is invalid + * 1 - key found and is valid + */ +int get_map_option(const char *str, const char *key, int *pint) +{ + const char *start = str; + const char *end = str; + int found = 0; + + do { + end++; + /* Search a for a field seperated by ',' */ + if ((*end == ',') || (*end == '\0')) { + found = parse_map_field(key, start, end - start, pint); + + /* set start to beginning of next field */ + start = end + 1; + } + } while ((*end) && (!found)); + + return found; +} +EXPORT_SYMBOL(get_map_option); /** * memparse - parse a string with mem suffixes into a number @@ -146,8 +220,4 @@ unsigned long long memparse (char *ptr, } return ret; } - - EXPORT_SYMBOL(memparse); -EXPORT_SYMBOL(get_option); -EXPORT_SYMBOL(get_options);