168 lines · c
1/*2 * Extracted fronm glob.c3 */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 */11static bool verbose = false;12module_param(verbose, bool, 0);13 14struct glob_test {15 char const *pat, *str;16 bool expected;17};18 19static 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 else37 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 simpler45 * to place that array in the .init.rodata section. The obvious46 * "array of structures containing char *" has no way to force the47 * 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 string52 * 3. String to match against: null-terminated string53 *54 * The list of tests is terminated with a final '\0' instead of55 * a glob_match result character.56 */57static 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 129static 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 the140 * end of the tests. Then come two null-terminated strings: the141 * 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 */161static void __exit glob_fini(void) { }162 163module_init(glob_init);164module_exit(glob_fini);165 166MODULE_DESCRIPTION("glob(7) matching tests");167MODULE_LICENSE("Dual MIT/GPL");168