Root/
1 | /* |
2 | * lib/parser.c - simple parser for mount, etc. options. |
3 | * |
4 | * This source code is licensed under the GNU General Public License, |
5 | * Version 2. See the file COPYING for more details. |
6 | */ |
7 | |
8 | #include <linux/ctype.h> |
9 | #include <linux/module.h> |
10 | #include <linux/parser.h> |
11 | #include <linux/slab.h> |
12 | #include <linux/string.h> |
13 | |
14 | /** |
15 | * match_one: - Determines if a string matches a simple pattern |
16 | * @s: the string to examine for presense of the pattern |
17 | * @p: the string containing the pattern |
18 | * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match |
19 | * locations. |
20 | * |
21 | * Description: Determines if the pattern @p is present in string @s. Can only |
22 | * match extremely simple token=arg style patterns. If the pattern is found, |
23 | * the location(s) of the arguments will be returned in the @args array. |
24 | */ |
25 | static int match_one(char *s, const char *p, substring_t args[]) |
26 | { |
27 | char *meta; |
28 | int argc = 0; |
29 | |
30 | if (!p) |
31 | return 1; |
32 | |
33 | while(1) { |
34 | int len = -1; |
35 | meta = strchr(p, '%'); |
36 | if (!meta) |
37 | return strcmp(p, s) == 0; |
38 | |
39 | if (strncmp(p, s, meta-p)) |
40 | return 0; |
41 | |
42 | s += meta - p; |
43 | p = meta + 1; |
44 | |
45 | if (isdigit(*p)) |
46 | len = simple_strtoul(p, (char **) &p, 10); |
47 | else if (*p == '%') { |
48 | if (*s++ != '%') |
49 | return 0; |
50 | p++; |
51 | continue; |
52 | } |
53 | |
54 | if (argc >= MAX_OPT_ARGS) |
55 | return 0; |
56 | |
57 | args[argc].from = s; |
58 | switch (*p++) { |
59 | case 's': { |
60 | size_t str_len = strlen(s); |
61 | |
62 | if (str_len == 0) |
63 | return 0; |
64 | if (len == -1 || len > str_len) |
65 | len = str_len; |
66 | args[argc].to = s + len; |
67 | break; |
68 | } |
69 | case 'd': |
70 | simple_strtol(s, &args[argc].to, 0); |
71 | goto num; |
72 | case 'u': |
73 | simple_strtoul(s, &args[argc].to, 0); |
74 | goto num; |
75 | case 'o': |
76 | simple_strtoul(s, &args[argc].to, 8); |
77 | goto num; |
78 | case 'x': |
79 | simple_strtoul(s, &args[argc].to, 16); |
80 | num: |
81 | if (args[argc].to == args[argc].from) |
82 | return 0; |
83 | break; |
84 | default: |
85 | return 0; |
86 | } |
87 | s = args[argc].to; |
88 | argc++; |
89 | } |
90 | } |
91 | |
92 | /** |
93 | * match_token: - Find a token (and optional args) in a string |
94 | * @s: the string to examine for token/argument pairs |
95 | * @table: match_table_t describing the set of allowed option tokens and the |
96 | * arguments that may be associated with them. Must be terminated with a |
97 | * &struct match_token whose pattern is set to the NULL pointer. |
98 | * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match |
99 | * locations. |
100 | * |
101 | * Description: Detects which if any of a set of token strings has been passed |
102 | * to it. Tokens can include up to MAX_OPT_ARGS instances of basic c-style |
103 | * format identifiers which will be taken into account when matching the |
104 | * tokens, and whose locations will be returned in the @args array. |
105 | */ |
106 | int match_token(char *s, const match_table_t table, substring_t args[]) |
107 | { |
108 | const struct match_token *p; |
109 | |
110 | for (p = table; !match_one(s, p->pattern, args) ; p++) |
111 | ; |
112 | |
113 | return p->token; |
114 | } |
115 | |
116 | /** |
117 | * match_number: scan a number in the given base from a substring_t |
118 | * @s: substring to be scanned |
119 | * @result: resulting integer on success |
120 | * @base: base to use when converting string |
121 | * |
122 | * Description: Given a &substring_t and a base, attempts to parse the substring |
123 | * as a number in that base. On success, sets @result to the integer represented |
124 | * by the string and returns 0. Returns either -ENOMEM or -EINVAL on failure. |
125 | */ |
126 | static int match_number(substring_t *s, int *result, int base) |
127 | { |
128 | char *endp; |
129 | char *buf; |
130 | int ret; |
131 | |
132 | buf = kmalloc(s->to - s->from + 1, GFP_KERNEL); |
133 | if (!buf) |
134 | return -ENOMEM; |
135 | memcpy(buf, s->from, s->to - s->from); |
136 | buf[s->to - s->from] = '\0'; |
137 | *result = simple_strtol(buf, &endp, base); |
138 | ret = 0; |
139 | if (endp == buf) |
140 | ret = -EINVAL; |
141 | kfree(buf); |
142 | return ret; |
143 | } |
144 | |
145 | /** |
146 | * match_int: - scan a decimal representation of an integer from a substring_t |
147 | * @s: substring_t to be scanned |
148 | * @result: resulting integer on success |
149 | * |
150 | * Description: Attempts to parse the &substring_t @s as a decimal integer. On |
151 | * success, sets @result to the integer represented by the string and returns 0. |
152 | * Returns either -ENOMEM or -EINVAL on failure. |
153 | */ |
154 | int match_int(substring_t *s, int *result) |
155 | { |
156 | return match_number(s, result, 0); |
157 | } |
158 | |
159 | /** |
160 | * match_octal: - scan an octal representation of an integer from a substring_t |
161 | * @s: substring_t to be scanned |
162 | * @result: resulting integer on success |
163 | * |
164 | * Description: Attempts to parse the &substring_t @s as an octal integer. On |
165 | * success, sets @result to the integer represented by the string and returns |
166 | * 0. Returns either -ENOMEM or -EINVAL on failure. |
167 | */ |
168 | int match_octal(substring_t *s, int *result) |
169 | { |
170 | return match_number(s, result, 8); |
171 | } |
172 | |
173 | /** |
174 | * match_hex: - scan a hex representation of an integer from a substring_t |
175 | * @s: substring_t to be scanned |
176 | * @result: resulting integer on success |
177 | * |
178 | * Description: Attempts to parse the &substring_t @s as a hexadecimal integer. |
179 | * On success, sets @result to the integer represented by the string and |
180 | * returns 0. Returns either -ENOMEM or -EINVAL on failure. |
181 | */ |
182 | int match_hex(substring_t *s, int *result) |
183 | { |
184 | return match_number(s, result, 16); |
185 | } |
186 | |
187 | /** |
188 | * match_strlcpy: - Copy the characters from a substring_t to a sized buffer |
189 | * @dest: where to copy to |
190 | * @src: &substring_t to copy |
191 | * @size: size of destination buffer |
192 | * |
193 | * Description: Copy the characters in &substring_t @src to the |
194 | * c-style string @dest. Copy no more than @size - 1 characters, plus |
195 | * the terminating NUL. Return length of @src. |
196 | */ |
197 | size_t match_strlcpy(char *dest, const substring_t *src, size_t size) |
198 | { |
199 | size_t ret = src->to - src->from; |
200 | |
201 | if (size) { |
202 | size_t len = ret >= size ? size - 1 : ret; |
203 | memcpy(dest, src->from, len); |
204 | dest[len] = '\0'; |
205 | } |
206 | return ret; |
207 | } |
208 | |
209 | /** |
210 | * match_strdup: - allocate a new string with the contents of a substring_t |
211 | * @s: &substring_t to copy |
212 | * |
213 | * Description: Allocates and returns a string filled with the contents of |
214 | * the &substring_t @s. The caller is responsible for freeing the returned |
215 | * string with kfree(). |
216 | */ |
217 | char *match_strdup(const substring_t *s) |
218 | { |
219 | size_t sz = s->to - s->from + 1; |
220 | char *p = kmalloc(sz, GFP_KERNEL); |
221 | if (p) |
222 | match_strlcpy(p, s, sz); |
223 | return p; |
224 | } |
225 | |
226 | EXPORT_SYMBOL(match_token); |
227 | EXPORT_SYMBOL(match_int); |
228 | EXPORT_SYMBOL(match_octal); |
229 | EXPORT_SYMBOL(match_hex); |
230 | EXPORT_SYMBOL(match_strlcpy); |
231 | EXPORT_SYMBOL(match_strdup); |
232 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9