Line data Source code
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 0 : static int get_range(char **str, int *pint)
26 : {
27 : int x, inc_counter, upper_range;
28 :
29 0 : (*str)++;
30 0 : upper_range = simple_strtol((*str), NULL, 0);
31 0 : inc_counter = upper_range - *pint;
32 0 : for (x = *pint; x < upper_range; x++)
33 0 : *pint++ = x;
34 0 : 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 0 : int get_option(char **str, int *pint)
53 : {
54 0 : char *cur = *str;
55 :
56 0 : if (!cur || !(*cur))
57 : return 0;
58 0 : *pint = simple_strtol(cur, str, 0);
59 0 : if (cur == *str)
60 : return 0;
61 0 : if (**str == ',') {
62 0 : (*str)++;
63 0 : return 2;
64 : }
65 0 : if (**str == '-')
66 : return 3;
67 :
68 0 : 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 0 : char *get_options(const char *str, int nints, int *ints)
90 : {
91 : int res, i = 1;
92 :
93 0 : while (i < nints) {
94 0 : res = get_option((char **)&str, ints + i);
95 0 : if (res == 0)
96 : break;
97 0 : if (res == 3) {
98 : int range_nums;
99 0 : range_nums = get_range((char **)&str, ints + i);
100 0 : 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 0 : i += (range_nums - 1);
108 : }
109 0 : i++;
110 0 : if (res == 1)
111 : break;
112 : }
113 0 : ints[0] = i - 1;
114 0 : 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, M, G, T, P, E.
125 : */
126 :
127 11 : unsigned long long memparse(const char *ptr, char **retptr)
128 : {
129 : char *endptr; /* local pointer to end of parsed string */
130 :
131 11 : unsigned long long ret = simple_strtoull(ptr, &endptr, 0);
132 :
133 11 : switch (*endptr) {
134 : case 'E':
135 : case 'e':
136 0 : ret <<= 10;
137 : case 'P':
138 : case 'p':
139 0 : ret <<= 10;
140 : case 'T':
141 : case 't':
142 0 : ret <<= 10;
143 : case 'G':
144 : case 'g':
145 0 : ret <<= 10;
146 : case 'M':
147 : case 'm':
148 2 : ret <<= 10;
149 : case 'K':
150 : case 'k':
151 7 : ret <<= 10;
152 7 : endptr++;
153 : default:
154 : break;
155 : }
156 :
157 11 : if (retptr)
158 11 : *retptr = endptr;
159 :
160 11 : return ret;
161 : }
162 : EXPORT_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 : */
174 0 : bool parse_option_str(const char *str, const char *option)
175 : {
176 0 : while (*str) {
177 0 : if (!strncmp(str, option, strlen(option))) {
178 0 : str += strlen(option);
179 0 : if (!*str || *str == ',')
180 : return true;
181 : }
182 :
183 0 : while (*str && *str != ',')
184 0 : str++;
185 :
186 0 : if (*str == ',')
187 0 : str++;
188 : }
189 :
190 : return false;
191 : }
|