Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Geert Uytterhoeven and committed by
Linus Torvalds
ba95b045 5fb7f874

+169 -166
+1 -2
lib/Kconfig
··· 431 431 depends on this. 432 432 433 433 config GLOB_SELFTEST 434 - bool "glob self-test on init" 435 - default n 434 + tristate "glob self-test on init" 436 435 depends on GLOB 437 436 help 438 437 This option enables a simple self-test of the glob_match
+1
lib/Makefile
··· 162 162 obj-$(CONFIG_DQL) += dynamic_queue_limits.o 163 163 164 164 obj-$(CONFIG_GLOB) += glob.o 165 + obj-$(CONFIG_GLOB_SELFTEST) += globtest.o 165 166 166 167 obj-$(CONFIG_MPILIB) += mpi/ 167 168 obj-$(CONFIG_SIGNATURE) += digsig.o
-164
lib/glob.c
··· 121 121 } 122 122 } 123 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 */
+167
lib/globtest.c
··· 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");