diff options
author | Geert Uytterhoeven <geert@linux-m68k.org> | 2017-02-24 18:00:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-24 20:46:57 -0500 |
commit | ba95b045e94fe15cace3a7d3a20fbedb2c6a817e (patch) | |
tree | 12e84736e1adedf5ecfb7931941dd9ebb3698479 | |
parent | 5fb7f87408f1534f2c3fadb876dc429cca601104 (diff) |
lib: add module support to glob tests
Extract the glob test code into its own source file, to allow to compile
it either to a loadable module, or builtin into the kernel.
Link: http://lkml.kernel.org/r/1483470276-10517-2-git-send-email-geert@linux-m68k.org
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | lib/Kconfig | 3 | ||||
-rw-r--r-- | lib/Makefile | 1 | ||||
-rw-r--r-- | lib/glob.c | 164 | ||||
-rw-r--r-- | lib/globtest.c | 167 |
4 files changed, 169 insertions, 166 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index ffd7635efda6..fe7e8e175db8 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
@@ -431,8 +431,7 @@ config GLOB | |||
431 | depends on this. | 431 | depends on this. |
432 | 432 | ||
433 | config GLOB_SELFTEST | 433 | config GLOB_SELFTEST |
434 | bool "glob self-test on init" | 434 | tristate "glob self-test on init" |
435 | default n | ||
436 | depends on GLOB | 435 | depends on GLOB |
437 | help | 436 | help |
438 | This option enables a simple self-test of the glob_match | 437 | This option enables a simple self-test of the glob_match |
diff --git a/lib/Makefile b/lib/Makefile index bc9be67b5f8b..d6d53b70f58d 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -162,6 +162,7 @@ obj-$(CONFIG_CORDIC) += cordic.o | |||
162 | obj-$(CONFIG_DQL) += dynamic_queue_limits.o | 162 | obj-$(CONFIG_DQL) += dynamic_queue_limits.o |
163 | 163 | ||
164 | obj-$(CONFIG_GLOB) += glob.o | 164 | obj-$(CONFIG_GLOB) += glob.o |
165 | obj-$(CONFIG_GLOB_SELFTEST) += globtest.o | ||
165 | 166 | ||
166 | obj-$(CONFIG_MPILIB) += mpi/ | 167 | obj-$(CONFIG_MPILIB) += mpi/ |
167 | obj-$(CONFIG_SIGNATURE) += digsig.o | 168 | obj-$(CONFIG_SIGNATURE) += digsig.o |
diff --git a/lib/glob.c b/lib/glob.c index 500fc80d23e1..0ba3ea86b546 100644 --- a/lib/glob.c +++ b/lib/glob.c | |||
@@ -121,167 +121,3 @@ backtrack: | |||
121 | } | 121 | } |
122 | } | 122 | } |
123 | EXPORT_SYMBOL(glob_match); | 123 | EXPORT_SYMBOL(glob_match); |
124 | |||
125 | |||
126 | #ifdef CONFIG_GLOB_SELFTEST | ||
127 | |||
128 | #include <linux/printk.h> | ||
129 | #include <linux/moduleparam.h> | ||
130 | |||
131 | /* Boot with "glob.verbose=1" to show successful tests, too */ | ||
132 | static bool verbose = false; | ||
133 | module_param(verbose, bool, 0); | ||
134 | |||
135 | struct glob_test { | ||
136 | char const *pat, *str; | ||
137 | bool expected; | ||
138 | }; | ||
139 | |||
140 | static bool __pure __init test(char const *pat, char const *str, bool expected) | ||
141 | { | ||
142 | bool match = glob_match(pat, str); | ||
143 | bool success = match == expected; | ||
144 | |||
145 | /* Can't get string literals into a particular section, so... */ | ||
146 | static char const msg_error[] __initconst = | ||
147 | KERN_ERR "glob: \"%s\" vs. \"%s\": %s *** ERROR ***\n"; | ||
148 | static char const msg_ok[] __initconst = | ||
149 | KERN_DEBUG "glob: \"%s\" vs. \"%s\": %s OK\n"; | ||
150 | static char const mismatch[] __initconst = "mismatch"; | ||
151 | char const *message; | ||
152 | |||
153 | if (!success) | ||
154 | message = msg_error; | ||
155 | else if (verbose) | ||
156 | message = msg_ok; | ||
157 | else | ||
158 | return success; | ||
159 | |||
160 | printk(message, pat, str, mismatch + 3*match); | ||
161 | return success; | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * The tests are all jammed together in one array to make it simpler | ||
166 | * to place that array in the .init.rodata section. The obvious | ||
167 | * "array of structures containing char *" has no way to force the | ||
168 | * pointed-to strings to be in a particular section. | ||
169 | * | ||
170 | * Anyway, a test consists of: | ||
171 | * 1. Expected glob_match result: '1' or '0'. | ||
172 | * 2. Pattern to match: null-terminated string | ||
173 | * 3. String to match against: null-terminated string | ||
174 | * | ||
175 | * The list of tests is terminated with a final '\0' instead of | ||
176 | * a glob_match result character. | ||
177 | */ | ||
178 | static char const glob_tests[] __initconst = | ||
179 | /* Some basic tests */ | ||
180 | "1" "a\0" "a\0" | ||
181 | "0" "a\0" "b\0" | ||
182 | "0" "a\0" "aa\0" | ||
183 | "0" "a\0" "\0" | ||
184 | "1" "\0" "\0" | ||
185 | "0" "\0" "a\0" | ||
186 | /* Simple character class tests */ | ||
187 | "1" "[a]\0" "a\0" | ||
188 | "0" "[a]\0" "b\0" | ||
189 | "0" "[!a]\0" "a\0" | ||
190 | "1" "[!a]\0" "b\0" | ||
191 | "1" "[ab]\0" "a\0" | ||
192 | "1" "[ab]\0" "b\0" | ||
193 | "0" "[ab]\0" "c\0" | ||
194 | "1" "[!ab]\0" "c\0" | ||
195 | "1" "[a-c]\0" "b\0" | ||
196 | "0" "[a-c]\0" "d\0" | ||
197 | /* Corner cases in character class parsing */ | ||
198 | "1" "[a-c-e-g]\0" "-\0" | ||
199 | "0" "[a-c-e-g]\0" "d\0" | ||
200 | "1" "[a-c-e-g]\0" "f\0" | ||
201 | "1" "[]a-ceg-ik[]\0" "a\0" | ||
202 | "1" "[]a-ceg-ik[]\0" "]\0" | ||
203 | "1" "[]a-ceg-ik[]\0" "[\0" | ||
204 | "1" "[]a-ceg-ik[]\0" "h\0" | ||
205 | "0" "[]a-ceg-ik[]\0" "f\0" | ||
206 | "0" "[!]a-ceg-ik[]\0" "h\0" | ||
207 | "0" "[!]a-ceg-ik[]\0" "]\0" | ||
208 | "1" "[!]a-ceg-ik[]\0" "f\0" | ||
209 | /* Simple wild cards */ | ||
210 | "1" "?\0" "a\0" | ||
211 | "0" "?\0" "aa\0" | ||
212 | "0" "??\0" "a\0" | ||
213 | "1" "?x?\0" "axb\0" | ||
214 | "0" "?x?\0" "abx\0" | ||
215 | "0" "?x?\0" "xab\0" | ||
216 | /* Asterisk wild cards (backtracking) */ | ||
217 | "0" "*??\0" "a\0" | ||
218 | "1" "*??\0" "ab\0" | ||
219 | "1" "*??\0" "abc\0" | ||
220 | "1" "*??\0" "abcd\0" | ||
221 | "0" "??*\0" "a\0" | ||
222 | "1" "??*\0" "ab\0" | ||
223 | "1" "??*\0" "abc\0" | ||
224 | "1" "??*\0" "abcd\0" | ||
225 | "0" "?*?\0" "a\0" | ||
226 | "1" "?*?\0" "ab\0" | ||
227 | "1" "?*?\0" "abc\0" | ||
228 | "1" "?*?\0" "abcd\0" | ||
229 | "1" "*b\0" "b\0" | ||
230 | "1" "*b\0" "ab\0" | ||
231 | "0" "*b\0" "ba\0" | ||
232 | "1" "*b\0" "bb\0" | ||
233 | "1" "*b\0" "abb\0" | ||
234 | "1" "*b\0" "bab\0" | ||
235 | "1" "*bc\0" "abbc\0" | ||
236 | "1" "*bc\0" "bc\0" | ||
237 | "1" "*bc\0" "bbc\0" | ||
238 | "1" "*bc\0" "bcbc\0" | ||
239 | /* Multiple asterisks (complex backtracking) */ | ||
240 | "1" "*ac*\0" "abacadaeafag\0" | ||
241 | "1" "*ac*ae*ag*\0" "abacadaeafag\0" | ||
242 | "1" "*a*b*[bc]*[ef]*g*\0" "abacadaeafag\0" | ||
243 | "0" "*a*b*[ef]*[cd]*g*\0" "abacadaeafag\0" | ||
244 | "1" "*abcd*\0" "abcabcabcabcdefg\0" | ||
245 | "1" "*ab*cd*\0" "abcabcabcabcdefg\0" | ||
246 | "1" "*abcd*abcdef*\0" "abcabcdabcdeabcdefg\0" | ||
247 | "0" "*abcd*\0" "abcabcabcabcefg\0" | ||
248 | "0" "*ab*cd*\0" "abcabcabcabcefg\0"; | ||
249 | |||
250 | static int __init glob_init(void) | ||
251 | { | ||
252 | unsigned successes = 0; | ||
253 | unsigned n = 0; | ||
254 | char const *p = glob_tests; | ||
255 | static char const message[] __initconst = | ||
256 | KERN_INFO "glob: %u self-tests passed, %u failed\n"; | ||
257 | |||
258 | /* | ||
259 | * Tests are jammed together in a string. The first byte is '1' | ||
260 | * or '0' to indicate the expected outcome, or '\0' to indicate the | ||
261 | * end of the tests. Then come two null-terminated strings: the | ||
262 | * pattern and the string to match it against. | ||
263 | */ | ||
264 | while (*p) { | ||
265 | bool expected = *p++ & 1; | ||
266 | char const *pat = p; | ||
267 | |||
268 | p += strlen(p) + 1; | ||
269 | successes += test(pat, p, expected); | ||
270 | p += strlen(p) + 1; | ||
271 | n++; | ||
272 | } | ||
273 | |||
274 | n -= successes; | ||
275 | printk(message, successes, n); | ||
276 | |||
277 | /* What's the errno for "kernel bug detected"? Guess... */ | ||
278 | return n ? -ECANCELED : 0; | ||
279 | } | ||
280 | |||
281 | /* We need a dummy exit function to allow unload */ | ||
282 | static void __exit glob_fini(void) { } | ||
283 | |||
284 | module_init(glob_init); | ||
285 | module_exit(glob_fini); | ||
286 | |||
287 | #endif /* CONFIG_GLOB_SELFTEST */ | ||
diff --git a/lib/globtest.c b/lib/globtest.c new file mode 100644 index 000000000000..d8e97d43b905 --- /dev/null +++ b/lib/globtest.c | |||
@@ -0,0 +1,167 @@ | |||
1 | /* | ||
2 | * Extracted fronm glob.c | ||
3 | */ | ||
4 | |||
5 | #include <linux/module.h> | ||
6 | #include <linux/moduleparam.h> | ||
7 | #include <linux/glob.h> | ||
8 | #include <linux/printk.h> | ||
9 | |||
10 | /* Boot with "glob.verbose=1" to show successful tests, too */ | ||
11 | static bool verbose = false; | ||
12 | module_param(verbose, bool, 0); | ||
13 | |||
14 | struct glob_test { | ||
15 | char const *pat, *str; | ||
16 | bool expected; | ||
17 | }; | ||
18 | |||
19 | static bool __pure __init test(char const *pat, char const *str, bool expected) | ||
20 | { | ||
21 | bool match = glob_match(pat, str); | ||
22 | bool success = match == expected; | ||
23 | |||
24 | /* Can't get string literals into a particular section, so... */ | ||
25 | static char const msg_error[] __initconst = | ||
26 | KERN_ERR "glob: \"%s\" vs. \"%s\": %s *** ERROR ***\n"; | ||
27 | static char const msg_ok[] __initconst = | ||
28 | KERN_DEBUG "glob: \"%s\" vs. \"%s\": %s OK\n"; | ||
29 | static char const mismatch[] __initconst = "mismatch"; | ||
30 | char const *message; | ||
31 | |||
32 | if (!success) | ||
33 | message = msg_error; | ||
34 | else if (verbose) | ||
35 | message = msg_ok; | ||
36 | else | ||
37 | return success; | ||
38 | |||
39 | printk(message, pat, str, mismatch + 3*match); | ||
40 | return success; | ||
41 | } | ||
42 | |||
43 | /* | ||
44 | * The tests are all jammed together in one array to make it simpler | ||
45 | * to place that array in the .init.rodata section. The obvious | ||
46 | * "array of structures containing char *" has no way to force the | ||
47 | * pointed-to strings to be in a particular section. | ||
48 | * | ||
49 | * Anyway, a test consists of: | ||
50 | * 1. Expected glob_match result: '1' or '0'. | ||
51 | * 2. Pattern to match: null-terminated string | ||
52 | * 3. String to match against: null-terminated string | ||
53 | * | ||
54 | * The list of tests is terminated with a final '\0' instead of | ||
55 | * a glob_match result character. | ||
56 | */ | ||
57 | static char const glob_tests[] __initconst = | ||
58 | /* Some basic tests */ | ||
59 | "1" "a\0" "a\0" | ||
60 | "0" "a\0" "b\0" | ||
61 | "0" "a\0" "aa\0" | ||
62 | "0" "a\0" "\0" | ||
63 | "1" "\0" "\0" | ||
64 | "0" "\0" "a\0" | ||
65 | /* Simple character class tests */ | ||
66 | "1" "[a]\0" "a\0" | ||
67 | "0" "[a]\0" "b\0" | ||
68 | "0" "[!a]\0" "a\0" | ||
69 | "1" "[!a]\0" "b\0" | ||
70 | "1" "[ab]\0" "a\0" | ||
71 | "1" "[ab]\0" "b\0" | ||
72 | "0" "[ab]\0" "c\0" | ||
73 | "1" "[!ab]\0" "c\0" | ||
74 | "1" "[a-c]\0" "b\0" | ||
75 | "0" "[a-c]\0" "d\0" | ||
76 | /* Corner cases in character class parsing */ | ||
77 | "1" "[a-c-e-g]\0" "-\0" | ||
78 | "0" "[a-c-e-g]\0" "d\0" | ||
79 | "1" "[a-c-e-g]\0" "f\0" | ||
80 | "1" "[]a-ceg-ik[]\0" "a\0" | ||
81 | "1" "[]a-ceg-ik[]\0" "]\0" | ||
82 | "1" "[]a-ceg-ik[]\0" "[\0" | ||
83 | "1" "[]a-ceg-ik[]\0" "h\0" | ||
84 | "0" "[]a-ceg-ik[]\0" "f\0" | ||
85 | "0" "[!]a-ceg-ik[]\0" "h\0" | ||
86 | "0" "[!]a-ceg-ik[]\0" "]\0" | ||
87 | "1" "[!]a-ceg-ik[]\0" "f\0" | ||
88 | /* Simple wild cards */ | ||
89 | "1" "?\0" "a\0" | ||
90 | "0" "?\0" "aa\0" | ||
91 | "0" "??\0" "a\0" | ||
92 | "1" "?x?\0" "axb\0" | ||
93 | "0" "?x?\0" "abx\0" | ||
94 | "0" "?x?\0" "xab\0" | ||
95 | /* Asterisk wild cards (backtracking) */ | ||
96 | "0" "*??\0" "a\0" | ||
97 | "1" "*??\0" "ab\0" | ||
98 | "1" "*??\0" "abc\0" | ||
99 | "1" "*??\0" "abcd\0" | ||
100 | "0" "??*\0" "a\0" | ||
101 | "1" "??*\0" "ab\0" | ||
102 | "1" "??*\0" "abc\0" | ||
103 | "1" "??*\0" "abcd\0" | ||
104 | "0" "?*?\0" "a\0" | ||
105 | "1" "?*?\0" "ab\0" | ||
106 | "1" "?*?\0" "abc\0" | ||
107 | "1" "?*?\0" "abcd\0" | ||
108 | "1" "*b\0" "b\0" | ||
109 | "1" "*b\0" "ab\0" | ||
110 | "0" "*b\0" "ba\0" | ||
111 | "1" "*b\0" "bb\0" | ||
112 | "1" "*b\0" "abb\0" | ||
113 | "1" "*b\0" "bab\0" | ||
114 | "1" "*bc\0" "abbc\0" | ||
115 | "1" "*bc\0" "bc\0" | ||
116 | "1" "*bc\0" "bbc\0" | ||
117 | "1" "*bc\0" "bcbc\0" | ||
118 | /* Multiple asterisks (complex backtracking) */ | ||
119 | "1" "*ac*\0" "abacadaeafag\0" | ||
120 | "1" "*ac*ae*ag*\0" "abacadaeafag\0" | ||
121 | "1" "*a*b*[bc]*[ef]*g*\0" "abacadaeafag\0" | ||
122 | "0" "*a*b*[ef]*[cd]*g*\0" "abacadaeafag\0" | ||
123 | "1" "*abcd*\0" "abcabcabcabcdefg\0" | ||
124 | "1" "*ab*cd*\0" "abcabcabcabcdefg\0" | ||
125 | "1" "*abcd*abcdef*\0" "abcabcdabcdeabcdefg\0" | ||
126 | "0" "*abcd*\0" "abcabcabcabcefg\0" | ||
127 | "0" "*ab*cd*\0" "abcabcabcabcefg\0"; | ||
128 | |||
129 | static int __init glob_init(void) | ||
130 | { | ||
131 | unsigned successes = 0; | ||
132 | unsigned n = 0; | ||
133 | char const *p = glob_tests; | ||
134 | static char const message[] __initconst = | ||
135 | KERN_INFO "glob: %u self-tests passed, %u failed\n"; | ||
136 | |||
137 | /* | ||
138 | * Tests are jammed together in a string. The first byte is '1' | ||
139 | * or '0' to indicate the expected outcome, or '\0' to indicate the | ||
140 | * end of the tests. Then come two null-terminated strings: the | ||
141 | * pattern and the string to match it against. | ||
142 | */ | ||
143 | while (*p) { | ||
144 | bool expected = *p++ & 1; | ||
145 | char const *pat = p; | ||
146 | |||
147 | p += strlen(p) + 1; | ||
148 | successes += test(pat, p, expected); | ||
149 | p += strlen(p) + 1; | ||
150 | n++; | ||
151 | } | ||
152 | |||
153 | n -= successes; | ||
154 | printk(message, successes, n); | ||
155 | |||
156 | /* What's the errno for "kernel bug detected"? Guess... */ | ||
157 | return n ? -ECANCELED : 0; | ||
158 | } | ||
159 | |||
160 | /* We need a dummy exit function to allow unload */ | ||
161 | static void __exit glob_fini(void) { } | ||
162 | |||
163 | module_init(glob_init); | ||
164 | module_exit(glob_fini); | ||
165 | |||
166 | MODULE_DESCRIPTION("glob(7) matching tests"); | ||
167 | MODULE_LICENSE("Dual MIT/GPL"); | ||