linux/lib/cmdline.c
<<
>>
Prefs
   1/*
   2 * linux/lib/cmdline.c
   3 * Helper functions generally used for parsing kernel command line
   4 * and module options.
   5 *
   6 * Code and copyrights come from init/main.c and arch/i386/kernel/setup.c.
   7 *
   8 * This source code is licensed under the GNU General Public License,
   9 * Version 2.  See the file COPYING for more details.
  10 *
  11 * GNU Indent formatting options for this file: -kr -i8 -npsl -pcs
  12 *
  13 */
  14
  15#include <linux/export.h>
  16#include <linux/kernel.h>
  17#include <linux/string.h>
  18#include <linux/ctype.h>
  19
  20/*
  21 *      If a hyphen was found in get_option, this will handle the
  22 *      range of numbers, M-N.  This will expand the range and insert
  23 *      the values[M, M+1, ..., N] into the ints array in get_options.
  24 */
  25
  26static int get_range(char **str, int *pint, int n)
  27{
  28        int x, inc_counter, upper_range;
  29
  30        (*str)++;
  31        upper_range = simple_strtol((*str), NULL, 0);
  32        inc_counter = upper_range - *pint;
  33        for (x = *pint; n && x < upper_range; x++, n--)
  34                *pint++ = x;
  35        return inc_counter;
  36}
  37
  38/**
  39 *      get_option - Parse integer from an option string
  40 *      @str: option string
  41 *      @pint: (output) integer value parsed from @str
  42 *
  43 *      Read an int from an option string; if available accept a subsequent
  44 *      comma as well.
  45 *
  46 *      Return values:
  47 *      0 - no int in string
  48 *      1 - int found, no subsequent comma
  49 *      2 - int found including a subsequent comma
  50 *      3 - hyphen found to denote a range
  51 */
  52
  53int get_option(char **str, int *pint)
  54{
  55        char *cur = *str;
  56
  57        if (!cur || !(*cur))
  58                return 0;
  59        *pint = simple_strtol(cur, str, 0);
  60        if (cur == *str)
  61                return 0;
  62        if (**str == ',') {
  63                (*str)++;
  64                return 2;
  65        }
  66        if (**str == '-')
  67                return 3;
  68
  69        return 1;
  70}
  71EXPORT_SYMBOL(get_option);
  72
  73/**
  74 *      get_options - Parse a string into a list of integers
  75 *      @str: String to be parsed
  76 *      @nints: size of integer array
  77 *      @ints: integer array
  78 *
  79 *      This function parses a string containing a comma-separated
  80 *      list of integers, a hyphen-separated range of _positive_ integers,
  81 *      or a combination of both.  The parse halts when the array is
  82 *      full, or when no more numbers can be retrieved from the
  83 *      string.
  84 *
  85 *      Return value is the character in the string which caused
  86 *      the parse to end (typically a null terminator, if @str is
  87 *      completely parseable).
  88 */
  89
  90char *get_options(const char *str, int nints, int *ints)
  91{
  92        int res, i = 1;
  93
  94        while (i < nints) {
  95                res = get_option((char **)&str, ints + i);
  96                if (res == 0)
  97                        break;
  98                if (res == 3) {
  99                        int range_nums;
 100                        range_nums = get_range((char **)&str, ints + i, nints - i);
 101                        if (range_nums < 0)
 102                                break;
 103                        /*
 104                         * Decrement the result by one to leave out the
 105                         * last number in the range.  The next iteration
 106                         * will handle the upper number in the range
 107                         */
 108                        i += (range_nums - 1);
 109                }
 110                i++;
 111                if (res == 1)
 112                        break;
 113        }
 114        ints[0] = i - 1;
 115        return (char *)str;
 116}
 117EXPORT_SYMBOL(get_options);
 118
 119/**
 120 *      memparse - parse a string with mem suffixes into a number
 121 *      @ptr: Where parse begins
 122 *      @retptr: (output) Optional pointer to next char after parse completes
 123 *
 124 *      Parses a string into a number.  The number stored at @ptr is
 125 *      potentially suffixed with K, M, G, T, P, E.
 126 */
 127
 128unsigned long long memparse(const char *ptr, char **retptr)
 129{
 130        char *endptr;   /* local pointer to end of parsed string */
 131
 132        unsigned long long ret = simple_strtoull(ptr, &endptr, 0);
 133
 134        switch (*endptr) {
 135        case 'E':
 136        case 'e':
 137                ret <<= 10;
 138        case 'P':
 139        case 'p':
 140                ret <<= 10;
 141        case 'T':
 142        case 't':
 143                ret <<= 10;
 144        case 'G':
 145        case 'g':
 146                ret <<= 10;
 147        case 'M':
 148        case 'm':
 149                ret <<= 10;
 150        case 'K':
 151        case 'k':
 152                ret <<= 10;
 153                endptr++;
 154        default:
 155                break;
 156        }
 157
 158        if (retptr)
 159                *retptr = endptr;
 160
 161        return ret;
 162}
 163EXPORT_SYMBOL(memparse);
 164
 165/**
 166 *      parse_option_str - Parse a string and check an option is set or not
 167 *      @str: String to be parsed
 168 *      @option: option name
 169 *
 170 *      This function parses a string containing a comma-separated list of
 171 *      strings like a=b,c.
 172 *
 173 *      Return true if there's such option in the string, or return false.
 174 */
 175bool parse_option_str(const char *str, const char *option)
 176{
 177        while (*str) {
 178                if (!strncmp(str, option, strlen(option))) {
 179                        str += strlen(option);
 180                        if (!*str || *str == ',')
 181                                return true;
 182                }
 183
 184                while (*str && *str != ',')
 185                        str++;
 186
 187                if (*str == ',')
 188                        str++;
 189        }
 190
 191        return false;
 192}
 193
 194/*
 195 * Parse a string to get a param value pair.
 196 * You can use " around spaces, but can't escape ".
 197 * Hyphens and underscores equivalent in parameter names.
 198 */
 199char *next_arg(char *args, char **param, char **val)
 200{
 201        unsigned int i, equals = 0;
 202        int in_quote = 0, quoted = 0;
 203        char *next;
 204
 205        if (*args == '"') {
 206                args++;
 207                in_quote = 1;
 208                quoted = 1;
 209        }
 210
 211        for (i = 0; args[i]; i++) {
 212                if (isspace(args[i]) && !in_quote)
 213                        break;
 214                if (equals == 0) {
 215                        if (args[i] == '=')
 216                                equals = i;
 217                }
 218                if (args[i] == '"')
 219                        in_quote = !in_quote;
 220        }
 221
 222        *param = args;
 223        if (!equals)
 224                *val = NULL;
 225        else {
 226                args[equals] = '\0';
 227                *val = args + equals + 1;
 228
 229                /* Don't include quotes in value. */
 230                if (**val == '"') {
 231                        (*val)++;
 232                        if (args[i-1] == '"')
 233                                args[i-1] = '\0';
 234                }
 235        }
 236        if (quoted && args[i-1] == '"')
 237                args[i-1] = '\0';
 238
 239        if (args[i]) {
 240                args[i] = '\0';
 241                next = args + i + 1;
 242        } else
 243                next = args + i;
 244
 245        /* Chew up trailing spaces. */
 246        return skip_spaces(next);
 247}
 248