]> git.karo-electronics.de Git - karo-tx-linux.git/blob - lib/cmdline.c
Merge branch 'for-3.14/core' of git://git.kernel.dk/linux-block
[karo-tx-linux.git] / lib / cmdline.c
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
25 static 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
52 int 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 }
70 EXPORT_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
89 char *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 }
116 EXPORT_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 (for kilobytes, or 1024 bytes),
125  *      %M (for megabytes, or 1048576 bytes), or %G (for gigabytes, or
126  *      1073741824).  If the number is suffixed with K, M, or G, then
127  *      the return value is the number multiplied by one kilobyte, one
128  *      megabyte, or one gigabyte, respectively.
129  */
130
131 unsigned long long memparse(const char *ptr, char **retptr)
132 {
133         char *endptr;   /* local pointer to end of parsed string */
134
135         unsigned long long ret = simple_strtoull(ptr, &endptr, 0);
136
137         switch (*endptr) {
138         case 'G':
139         case 'g':
140                 ret <<= 10;
141         case 'M':
142         case 'm':
143                 ret <<= 10;
144         case 'K':
145         case 'k':
146                 ret <<= 10;
147                 endptr++;
148         default:
149                 break;
150         }
151
152         if (retptr)
153                 *retptr = endptr;
154
155         return ret;
156 }
157 EXPORT_SYMBOL(memparse);