Blame view

lib/cmdline.c 5.09 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*
   * linux/lib/cmdline.c
   * Helper functions generally used for parsing kernel command line
   * and module options.
   *
   * Code and copyrights come from init/main.c and arch/i386/kernel/setup.c.
   *
   * This source code is licensed under the GNU General Public License,
   * Version 2.  See the file COPYING for more details.
   *
   * GNU Indent formatting options for this file: -kr -i8 -npsl -pcs
   *
   */
8bc3bcc93   Paul Gortmaker   lib: reduce the u...
14
  #include <linux/export.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
16
  #include <linux/kernel.h>
  #include <linux/string.h>
f51b17c8d   Baoquan He   boot/param: Move ...
17
  #include <linux/ctype.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18

22f2e2801   Derek Fults   [PATCH] get_optio...
19
20
21
22
23
  /*
   *	If a hyphen was found in get_option, this will handle the
   *	range of numbers, M-N.  This will expand the range and insert
   *	the values[M, M+1, ..., N] into the ints array in get_options.
   */
a91e0f680   Ilya Matveychikov   lib/cmdline.c: fi...
24
  static int get_range(char **str, int *pint, int n)
22f2e2801   Derek Fults   [PATCH] get_optio...
25
26
27
28
29
30
  {
  	int x, inc_counter, upper_range;
  
  	(*str)++;
  	upper_range = simple_strtol((*str), NULL, 0);
  	inc_counter = upper_range - *pint;
a91e0f680   Ilya Matveychikov   lib/cmdline.c: fi...
31
  	for (x = *pint; n && x < upper_range; x++, n--)
22f2e2801   Derek Fults   [PATCH] get_optio...
32
33
34
  		*pint++ = x;
  	return inc_counter;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
37
38
39
40
41
42
43
44
  
  /**
   *	get_option - Parse integer from an option string
   *	@str: option string
   *	@pint: (output) integer value parsed from @str
   *
   *	Read an int from an option string; if available accept a subsequent
   *	comma as well.
   *
   *	Return values:
72fd4a35a   Robert P. J. Day   [PATCH] Numerous ...
45
46
47
48
   *	0 - no int in string
   *	1 - int found, no subsequent comma
   *	2 - int found including a subsequent comma
   *	3 - hyphen found to denote a range
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
   */
9fd430544   Felipe Contreras   lib/cmdline.c: fi...
50
  int get_option(char **str, int *pint)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
53
54
55
  {
  	char *cur = *str;
  
  	if (!cur || !(*cur))
  		return 0;
9fd430544   Felipe Contreras   lib/cmdline.c: fi...
56
  	*pint = simple_strtol(cur, str, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
60
61
62
  	if (cur == *str)
  		return 0;
  	if (**str == ',') {
  		(*str)++;
  		return 2;
  	}
22f2e2801   Derek Fults   [PATCH] get_optio...
63
64
  	if (**str == '-')
  		return 3;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
67
  
  	return 1;
  }
ff6f9bbb5   Felipe Contreras   lib/cmdline.c: de...
68
  EXPORT_SYMBOL(get_option);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
70
71
72
73
74
75
76
  
  /**
   *	get_options - Parse a string into a list of integers
   *	@str: String to be parsed
   *	@nints: size of integer array
   *	@ints: integer array
   *
   *	This function parses a string containing a comma-separated
22f2e2801   Derek Fults   [PATCH] get_optio...
77
78
   *	list of integers, a hyphen-separated range of _positive_ integers,
   *	or a combination of both.  The parse halts when the array is
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
80
81
82
83
84
85
   *	full, or when no more numbers can be retrieved from the
   *	string.
   *
   *	Return value is the character in the string which caused
   *	the parse to end (typically a null terminator, if @str is
   *	completely parseable).
   */
9fd430544   Felipe Contreras   lib/cmdline.c: fi...
86

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
88
89
90
91
  char *get_options(const char *str, int nints, int *ints)
  {
  	int res, i = 1;
  
  	while (i < nints) {
9fd430544   Felipe Contreras   lib/cmdline.c: fi...
92
  		res = get_option((char **)&str, ints + i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
94
  		if (res == 0)
  			break;
22f2e2801   Derek Fults   [PATCH] get_optio...
95
96
  		if (res == 3) {
  			int range_nums;
a91e0f680   Ilya Matveychikov   lib/cmdline.c: fi...
97
  			range_nums = get_range((char **)&str, ints + i, nints - i);
22f2e2801   Derek Fults   [PATCH] get_optio...
98
99
100
101
102
103
104
105
106
  			if (range_nums < 0)
  				break;
  			/*
  			 * Decrement the result by one to leave out the
  			 * last number in the range.  The next iteration
  			 * will handle the upper number in the range
  			 */
  			i += (range_nums - 1);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
108
109
110
111
112
113
  		i++;
  		if (res == 1)
  			break;
  	}
  	ints[0] = i - 1;
  	return (char *)str;
  }
ff6f9bbb5   Felipe Contreras   lib/cmdline.c: de...
114
  EXPORT_SYMBOL(get_options);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
115
116
117
118
  
  /**
   *	memparse - parse a string with mem suffixes into a number
   *	@ptr: Where parse begins
fd1938297   Robert P. J. Day   lib: allow mempar...
119
   *	@retptr: (output) Optional pointer to next char after parse completes
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
   *
   *	Parses a string into a number.  The number stored at @ptr is
e004f3c77   Gui Hecheng   lib/cmdline.c: ad...
122
   *	potentially suffixed with K, M, G, T, P, E.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
   */
d974ae379   Jeremy Fitzhardinge   generic, memparse...
124
  unsigned long long memparse(const char *ptr, char **retptr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
  {
fd1938297   Robert P. J. Day   lib: allow mempar...
126
  	char *endptr;	/* local pointer to end of parsed string */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127

fd1938297   Robert P. J. Day   lib: allow mempar...
128
129
130
  	unsigned long long ret = simple_strtoull(ptr, &endptr, 0);
  
  	switch (*endptr) {
e004f3c77   Gui Hecheng   lib/cmdline.c: ad...
131
132
133
134
135
136
137
138
139
  	case 'E':
  	case 'e':
  		ret <<= 10;
  	case 'P':
  	case 'p':
  		ret <<= 10;
  	case 'T':
  	case 't':
  		ret <<= 10;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
141
142
143
144
145
146
147
148
  	case 'G':
  	case 'g':
  		ret <<= 10;
  	case 'M':
  	case 'm':
  		ret <<= 10;
  	case 'K':
  	case 'k':
  		ret <<= 10;
fd1938297   Robert P. J. Day   lib: allow mempar...
149
  		endptr++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150
151
152
  	default:
  		break;
  	}
fd1938297   Robert P. J. Day   lib: allow mempar...
153
154
155
  
  	if (retptr)
  		*retptr = endptr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
  	return ret;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  EXPORT_SYMBOL(memparse);
6ccc72b87   Dave Young   lib: Add a generi...
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
  
  /**
   *	parse_option_str - Parse a string and check an option is set or not
   *	@str: String to be parsed
   *	@option: option name
   *
   *	This function parses a string containing a comma-separated list of
   *	strings like a=b,c.
   *
   *	Return true if there's such option in the string, or return false.
   */
  bool parse_option_str(const char *str, const char *option)
  {
  	while (*str) {
  		if (!strncmp(str, option, strlen(option))) {
  			str += strlen(option);
  			if (!*str || *str == ',')
  				return true;
  		}
  
  		while (*str && *str != ',')
  			str++;
  
  		if (*str == ',')
  			str++;
  	}
  
  	return false;
  }
f51b17c8d   Baoquan He   boot/param: Move ...
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
  
  /*
   * Parse a string to get a param value pair.
   * You can use " around spaces, but can't escape ".
   * Hyphens and underscores equivalent in parameter names.
   */
  char *next_arg(char *args, char **param, char **val)
  {
  	unsigned int i, equals = 0;
  	int in_quote = 0, quoted = 0;
  	char *next;
  
  	if (*args == '"') {
  		args++;
  		in_quote = 1;
  		quoted = 1;
  	}
  
  	for (i = 0; args[i]; i++) {
  		if (isspace(args[i]) && !in_quote)
  			break;
  		if (equals == 0) {
  			if (args[i] == '=')
  				equals = i;
  		}
  		if (args[i] == '"')
  			in_quote = !in_quote;
  	}
  
  	*param = args;
  	if (!equals)
  		*val = NULL;
  	else {
  		args[equals] = '\0';
  		*val = args + equals + 1;
  
  		/* Don't include quotes in value. */
  		if (**val == '"') {
  			(*val)++;
  			if (args[i-1] == '"')
  				args[i-1] = '\0';
  		}
  	}
  	if (quoted && args[i-1] == '"')
  		args[i-1] = '\0';
  
  	if (args[i]) {
  		args[i] = '\0';
  		next = args + i + 1;
  	} else
  		next = args + i;
  
  	/* Chew up trailing spaces. */
  	return skip_spaces(next);
f51b17c8d   Baoquan He   boot/param: Move ...
242
  }