Fix PCMCIA cut-and-paste cs.c bug introduced by the recent
[linux-2.6/history.git] / lib / parser.c
blob858061397fe2b53db7231f5c9546892c2aa2b27f
1 /*
2 * lib/parser.c - simple parser for mount, etc. options.
4 * This source code is licensed under the GNU General Public License,
5 * Version 2. See the file COPYING for more details.
6 */
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>
14 static int match_one(char *s, char *p, substring_t args[])
16 char *meta;
17 int argc = 0;
19 if (!p)
20 return 1;
22 while(1) {
23 int len = -1;
24 meta = strchr(p, '%');
25 if (!meta)
26 return strcmp(p, s) == 0;
28 if (strncmp(p, s, meta-p))
29 return 0;
31 s += meta - p;
32 p = meta + 1;
34 if (isdigit(*p))
35 len = simple_strtoul(p, &p, 10);
36 else if (*p == '%') {
37 if (*s++ != '%')
38 return 0;
39 continue;
42 if (argc >= MAX_OPT_ARGS)
43 return 0;
45 args[argc].from = s;
46 switch (*p++) {
47 case 's':
48 if (len == -1 || len > strlen(s))
49 len = strlen(s);
50 args[argc].to = s + len;
51 break;
52 case 'd':
53 simple_strtol(s, &args[argc].to, 0);
54 goto num;
55 case 'u':
56 simple_strtoul(s, &args[argc].to, 0);
57 goto num;
58 case 'o':
59 simple_strtoul(s, &args[argc].to, 8);
60 goto num;
61 case 'x':
62 simple_strtoul(s, &args[argc].to, 16);
63 num:
64 if (args[argc].to == args[argc].from)
65 return 0;
66 break;
67 default:
68 return 0;
70 s = args[argc].to;
71 argc++;
75 int match_token(char *s, match_table_t table, substring_t args[])
77 struct match_token *p;
79 for (p = table; !match_one(s, p->pattern, args) ; p++)
82 return p->token;
85 static int match_number(substring_t *s, int *result, int base)
87 char *endp;
88 char *buf;
89 int ret;
91 buf = kmalloc(s->to - s->from + 1, GFP_KERNEL);
92 if (!buf)
93 return -ENOMEM;
94 memcpy(buf, s->from, s->to - s->from);
95 buf[s->to - s->from] = '\0';
96 *result = simple_strtol(buf, &endp, base);
97 ret = 0;
98 if (endp == buf)
99 ret = -EINVAL;
100 kfree(buf);
101 return ret;
104 int match_int(substring_t *s, int *result)
106 return match_number(s, result, 0);
109 int match_octal(substring_t *s, int *result)
111 return match_number(s, result, 8);
114 int match_hex(substring_t *s, int *result)
116 return match_number(s, result, 16);
119 void match_strcpy(char *to, substring_t *s)
121 memcpy(to, s->from, s->to - s->from);
122 to[s->to - s->from] = '\0';
125 char *match_strdup(substring_t *s)
127 char *p = kmalloc(s->to - s->from + 1, GFP_KERNEL);
128 if (p)
129 match_strcpy(p, s);
130 return p;
133 EXPORT_SYMBOL(match_token);
134 EXPORT_SYMBOL(match_int);
135 EXPORT_SYMBOL(match_octal);
136 EXPORT_SYMBOL(match_hex);
137 EXPORT_SYMBOL(match_strcpy);
138 EXPORT_SYMBOL(match_strdup);