~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/lib/cmdline.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php