Back to home page

LXR

 
 

    


0001 /*
0002  * linux/lib/cmdline.c
0003  * Helper functions generally used for parsing kernel command line
0004  * and module options.
0005  *
0006  * Code and copyrights come from init/main.c and arch/i386/kernel/setup.c.
0007  *
0008  * This source code is licensed under the GNU General Public License,
0009  * Version 2.  See the file COPYING for more details.
0010  *
0011  * GNU Indent formatting options for this file: -kr -i8 -npsl -pcs
0012  *
0013  */
0014 
0015 #include <linux/export.h>
0016 #include <linux/kernel.h>
0017 #include <linux/string.h>
0018 
0019 /*
0020  *  If a hyphen was found in get_option, this will handle the
0021  *  range of numbers, M-N.  This will expand the range and insert
0022  *  the values[M, M+1, ..., N] into the ints array in get_options.
0023  */
0024 
0025 static int get_range(char **str, int *pint)
0026 {
0027     int x, inc_counter, upper_range;
0028 
0029     (*str)++;
0030     upper_range = simple_strtol((*str), NULL, 0);
0031     inc_counter = upper_range - *pint;
0032     for (x = *pint; x < upper_range; x++)
0033         *pint++ = x;
0034     return inc_counter;
0035 }
0036 
0037 /**
0038  *  get_option - Parse integer from an option string
0039  *  @str: option string
0040  *  @pint: (output) integer value parsed from @str
0041  *
0042  *  Read an int from an option string; if available accept a subsequent
0043  *  comma as well.
0044  *
0045  *  Return values:
0046  *  0 - no int in string
0047  *  1 - int found, no subsequent comma
0048  *  2 - int found including a subsequent comma
0049  *  3 - hyphen found to denote a range
0050  */
0051 
0052 int get_option(char **str, int *pint)
0053 {
0054     char *cur = *str;
0055 
0056     if (!cur || !(*cur))
0057         return 0;
0058     *pint = simple_strtol(cur, str, 0);
0059     if (cur == *str)
0060         return 0;
0061     if (**str == ',') {
0062         (*str)++;
0063         return 2;
0064     }
0065     if (**str == '-')
0066         return 3;
0067 
0068     return 1;
0069 }
0070 EXPORT_SYMBOL(get_option);
0071 
0072 /**
0073  *  get_options - Parse a string into a list of integers
0074  *  @str: String to be parsed
0075  *  @nints: size of integer array
0076  *  @ints: integer array
0077  *
0078  *  This function parses a string containing a comma-separated
0079  *  list of integers, a hyphen-separated range of _positive_ integers,
0080  *  or a combination of both.  The parse halts when the array is
0081  *  full, or when no more numbers can be retrieved from the
0082  *  string.
0083  *
0084  *  Return value is the character in the string which caused
0085  *  the parse to end (typically a null terminator, if @str is
0086  *  completely parseable).
0087  */
0088 
0089 char *get_options(const char *str, int nints, int *ints)
0090 {
0091     int res, i = 1;
0092 
0093     while (i < nints) {
0094         res = get_option((char **)&str, ints + i);
0095         if (res == 0)
0096             break;
0097         if (res == 3) {
0098             int range_nums;
0099             range_nums = get_range((char **)&str, ints + i);
0100             if (range_nums < 0)
0101                 break;
0102             /*
0103              * Decrement the result by one to leave out the
0104              * last number in the range.  The next iteration
0105              * will handle the upper number in the range
0106              */
0107             i += (range_nums - 1);
0108         }
0109         i++;
0110         if (res == 1)
0111             break;
0112     }
0113     ints[0] = i - 1;
0114     return (char *)str;
0115 }
0116 EXPORT_SYMBOL(get_options);
0117 
0118 /**
0119  *  memparse - parse a string with mem suffixes into a number
0120  *  @ptr: Where parse begins
0121  *  @retptr: (output) Optional pointer to next char after parse completes
0122  *
0123  *  Parses a string into a number.  The number stored at @ptr is
0124  *  potentially suffixed with K, M, G, T, P, E.
0125  */
0126 
0127 unsigned long long memparse(const char *ptr, char **retptr)
0128 {
0129     char *endptr;   /* local pointer to end of parsed string */
0130 
0131     unsigned long long ret = simple_strtoull(ptr, &endptr, 0);
0132 
0133     switch (*endptr) {
0134     case 'E':
0135     case 'e':
0136         ret <<= 10;
0137     case 'P':
0138     case 'p':
0139         ret <<= 10;
0140     case 'T':
0141     case 't':
0142         ret <<= 10;
0143     case 'G':
0144     case 'g':
0145         ret <<= 10;
0146     case 'M':
0147     case 'm':
0148         ret <<= 10;
0149     case 'K':
0150     case 'k':
0151         ret <<= 10;
0152         endptr++;
0153     default:
0154         break;
0155     }
0156 
0157     if (retptr)
0158         *retptr = endptr;
0159 
0160     return ret;
0161 }
0162 EXPORT_SYMBOL(memparse);
0163 
0164 /**
0165  *  parse_option_str - Parse a string and check an option is set or not
0166  *  @str: String to be parsed
0167  *  @option: option name
0168  *
0169  *  This function parses a string containing a comma-separated list of
0170  *  strings like a=b,c.
0171  *
0172  *  Return true if there's such option in the string, or return false.
0173  */
0174 bool parse_option_str(const char *str, const char *option)
0175 {
0176     while (*str) {
0177         if (!strncmp(str, option, strlen(option))) {
0178             str += strlen(option);
0179             if (!*str || *str == ',')
0180                 return true;
0181         }
0182 
0183         while (*str && *str != ',')
0184             str++;
0185 
0186         if (*str == ',')
0187             str++;
0188     }
0189 
0190     return false;
0191 }