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
  19/*
  20 *      If a hyphen was found in get_option, this will handle the
  21 *      range of numbers, M-N.  This will expand the range and insert
  22 *      the values[M, M+1, ..., N] into the ints array in get_options.
  23 */
  24
  25static int get_range(char **str, int *pint)
  26{
  27        int x, inc_counter, upper_range;
  28
  29        (*str)++;
  30        upper_range = simple_strtol((*str), NULL, 0);
  31        inc_counter = upper_range - *pint;
  32        for (x = *pint; x < upper_range; x++)
  33                *pint++ = x;
  34        return inc_counter;
  35}
  36
  37/**
  38 *      get_option - Parse integer from an option string
  39 *      @str: option string
  40 *      @pint: (output) integer value parsed from @str
  41 *
  42 *      Read an int from an option string; if available accept a subsequent
  43 *      comma as well.
  44 *
  45 *      Return values:
  46 *      0 - no int in string
  47 *      1 - int found, no subsequent comma
  48 *      2 - int found including a subsequent comma
  49 *      3 - hyphen found to denote a range
  50 */
  51
  52int get_option(char **str, int *pint)
  53{
  54        char *cur = *str;
  55
  56        if (!cur || !(*cur))
  57                return 0;
  58        *pint = simple_strtol(cur, str, 0);
  59        if (cur == *str)
  60                return 0;
  61        if (**str == ',') {
  62                (*str)++;
  63                return 2;
  64        }
  65        if (**str == '-')
  66                return 3;
  67
  68        return 1;
  69}
  70EXPORT_SYMBOL(get_option);
  71
  72/**
  73 *      get_options - Parse a string into a list of integers
  74 *      @str: String to be parsed
  75 *      @nints: size of integer array
  76 *      @ints: integer array
  77 *
  78 *      This function parses a string containing a comma-separated
  79 *      list of integers, a hyphen-separated range of _positive_ integers,
  80 *      or a combination of both.  The parse halts when the array is
  81 *      full, or when no more numbers can be retrieved from the
  82 *      string.
  83 *
  84 *      Return value is the character in the string which caused
  85 *      the parse to end (typically a null terminator, if @str is
  86 *      completely parseable).
  87 */
  88
  89char *get_options(const char *str, int nints, int *ints)
  90{
  91        int res, i = 1;
  92
  93        while (i < nints) {
  94                res = get_option((char **)&str, ints + i);
  95                if (res == 0)
  96                        break;
  97                if (res == 3) {
  98                        int range_nums;
  99                        range_nums = get_range((char **)&str, ints + i);
 100                        if (range_nums < 0)
 101                                break;
 102                        /*
 103                         * Decrement the result by one to leave out the
 104                         * last number in the range.  The next iteration
 105                         * will handle the upper number in the range
 106                         */
 107                        i += (range_nums - 1);
 108                }
 109                i++;
 110                if (res == 1)
 111                        break;
 112        }
 113        ints[0] = i - 1;
 114        return (char *)str;
 115}
 116EXPORT_SYMBOL(get_options);
 117
 118/**
 119 *      memparse - parse a string with mem suffixes into a number
 120 *      @ptr: Where parse begins
 121 *      @retptr: (output) Optional pointer to next char after parse completes
 122 *
 123 *      Parses a string into a number.  The number stored at @ptr is
 124 *      potentially suffixed with K, M, G, T, P, E.
 125 */
 126
 127unsigned long long memparse(const char *ptr, char **retptr)
 128{
 129        char *endptr;   /* local pointer to end of parsed string */
 130
 131        unsigned long long ret = simple_strtoull(ptr, &endptr, 0);
 132
 133        switch (*endptr) {
 134        case 'E':
 135        case 'e':
 136                ret <<= 10;
 137        case 'P':
 138        case 'p':
 139                ret <<= 10;
 140        case 'T':
 141        case 't':
 142                ret <<= 10;
 143        case 'G':
 144        case 'g':
 145                ret <<= 10;
 146        case 'M':
 147        case 'm':
 148                ret <<= 10;
 149        case 'K':
 150        case 'k':
 151                ret <<= 10;
 152                endptr++;
 153        default:
 154                break;
 155        }
 156
 157        if (retptr)
 158                *retptr = endptr;
 159
 160        return ret;
 161}
 162EXPORT_SYMBOL(memparse);
 163
 164/**
 165 *      parse_option_str - Parse a string and check an option is set or not
 166 *      @str: String to be parsed
 167 *      @option: option name
 168 *
 169 *      This function parses a string containing a comma-separated list of
 170 *      strings like a=b,c.
 171 *
 172 *      Return true if there's such option in the string, or return false.
 173 */
 174bool parse_option_str(const char *str, const char *option)
 175{
 176        while (*str) {
 177                if (!strncmp(str, option, strlen(option))) {
 178                        str += strlen(option);
 179                        if (!*str || *str == ',')
 180                                return true;
 181                }
 182
 183                while (*str && *str != ',')
 184                        str++;
 185
 186                if (*str == ',')
 187                        str++;
 188        }
 189
 190        return false;
 191}
 192