Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Extracted fronm glob.c
0003  */
0004 
0005 #include <linux/module.h>
0006 #include <linux/moduleparam.h>
0007 #include <linux/glob.h>
0008 #include <linux/printk.h>
0009 
0010 /* Boot with "glob.verbose=1" to show successful tests, too */
0011 static bool verbose = false;
0012 module_param(verbose, bool, 0);
0013 
0014 struct glob_test {
0015     char const *pat, *str;
0016     bool expected;
0017 };
0018 
0019 static bool __pure __init test(char const *pat, char const *str, bool expected)
0020 {
0021     bool match = glob_match(pat, str);
0022     bool success = match == expected;
0023 
0024     /* Can't get string literals into a particular section, so... */
0025     static char const msg_error[] __initconst =
0026         KERN_ERR "glob: \"%s\" vs. \"%s\": %s *** ERROR ***\n";
0027     static char const msg_ok[] __initconst =
0028         KERN_DEBUG "glob: \"%s\" vs. \"%s\": %s OK\n";
0029     static char const mismatch[] __initconst = "mismatch";
0030     char const *message;
0031 
0032     if (!success)
0033         message = msg_error;
0034     else if (verbose)
0035         message = msg_ok;
0036     else
0037         return success;
0038 
0039     printk(message, pat, str, mismatch + 3*match);
0040     return success;
0041 }
0042 
0043 /*
0044  * The tests are all jammed together in one array to make it simpler
0045  * to place that array in the .init.rodata section.  The obvious
0046  * "array of structures containing char *" has no way to force the
0047  * pointed-to strings to be in a particular section.
0048  *
0049  * Anyway, a test consists of:
0050  * 1. Expected glob_match result: '1' or '0'.
0051  * 2. Pattern to match: null-terminated string
0052  * 3. String to match against: null-terminated string
0053  *
0054  * The list of tests is terminated with a final '\0' instead of
0055  * a glob_match result character.
0056  */
0057 static char const glob_tests[] __initconst =
0058     /* Some basic tests */
0059     "1" "a\0" "a\0"
0060     "0" "a\0" "b\0"
0061     "0" "a\0" "aa\0"
0062     "0" "a\0" "\0"
0063     "1" "\0" "\0"
0064     "0" "\0" "a\0"
0065     /* Simple character class tests */
0066     "1" "[a]\0" "a\0"
0067     "0" "[a]\0" "b\0"
0068     "0" "[!a]\0" "a\0"
0069     "1" "[!a]\0" "b\0"
0070     "1" "[ab]\0" "a\0"
0071     "1" "[ab]\0" "b\0"
0072     "0" "[ab]\0" "c\0"
0073     "1" "[!ab]\0" "c\0"
0074     "1" "[a-c]\0" "b\0"
0075     "0" "[a-c]\0" "d\0"
0076     /* Corner cases in character class parsing */
0077     "1" "[a-c-e-g]\0" "-\0"
0078     "0" "[a-c-e-g]\0" "d\0"
0079     "1" "[a-c-e-g]\0" "f\0"
0080     "1" "[]a-ceg-ik[]\0" "a\0"
0081     "1" "[]a-ceg-ik[]\0" "]\0"
0082     "1" "[]a-ceg-ik[]\0" "[\0"
0083     "1" "[]a-ceg-ik[]\0" "h\0"
0084     "0" "[]a-ceg-ik[]\0" "f\0"
0085     "0" "[!]a-ceg-ik[]\0" "h\0"
0086     "0" "[!]a-ceg-ik[]\0" "]\0"
0087     "1" "[!]a-ceg-ik[]\0" "f\0"
0088     /* Simple wild cards */
0089     "1" "?\0" "a\0"
0090     "0" "?\0" "aa\0"
0091     "0" "??\0" "a\0"
0092     "1" "?x?\0" "axb\0"
0093     "0" "?x?\0" "abx\0"
0094     "0" "?x?\0" "xab\0"
0095     /* Asterisk wild cards (backtracking) */
0096     "0" "*??\0" "a\0"
0097     "1" "*??\0" "ab\0"
0098     "1" "*??\0" "abc\0"
0099     "1" "*??\0" "abcd\0"
0100     "0" "??*\0" "a\0"
0101     "1" "??*\0" "ab\0"
0102     "1" "??*\0" "abc\0"
0103     "1" "??*\0" "abcd\0"
0104     "0" "?*?\0" "a\0"
0105     "1" "?*?\0" "ab\0"
0106     "1" "?*?\0" "abc\0"
0107     "1" "?*?\0" "abcd\0"
0108     "1" "*b\0" "b\0"
0109     "1" "*b\0" "ab\0"
0110     "0" "*b\0" "ba\0"
0111     "1" "*b\0" "bb\0"
0112     "1" "*b\0" "abb\0"
0113     "1" "*b\0" "bab\0"
0114     "1" "*bc\0" "abbc\0"
0115     "1" "*bc\0" "bc\0"
0116     "1" "*bc\0" "bbc\0"
0117     "1" "*bc\0" "bcbc\0"
0118     /* Multiple asterisks (complex backtracking) */
0119     "1" "*ac*\0" "abacadaeafag\0"
0120     "1" "*ac*ae*ag*\0" "abacadaeafag\0"
0121     "1" "*a*b*[bc]*[ef]*g*\0" "abacadaeafag\0"
0122     "0" "*a*b*[ef]*[cd]*g*\0" "abacadaeafag\0"
0123     "1" "*abcd*\0" "abcabcabcabcdefg\0"
0124     "1" "*ab*cd*\0" "abcabcabcabcdefg\0"
0125     "1" "*abcd*abcdef*\0" "abcabcdabcdeabcdefg\0"
0126     "0" "*abcd*\0" "abcabcabcabcefg\0"
0127     "0" "*ab*cd*\0" "abcabcabcabcefg\0";
0128 
0129 static int __init glob_init(void)
0130 {
0131     unsigned successes = 0;
0132     unsigned n = 0;
0133     char const *p = glob_tests;
0134     static char const message[] __initconst =
0135         KERN_INFO "glob: %u self-tests passed, %u failed\n";
0136 
0137     /*
0138      * Tests are jammed together in a string.  The first byte is '1'
0139      * or '0' to indicate the expected outcome, or '\0' to indicate the
0140      * end of the tests.  Then come two null-terminated strings: the
0141      * pattern and the string to match it against.
0142      */
0143     while (*p) {
0144         bool expected = *p++ & 1;
0145         char const *pat = p;
0146 
0147         p += strlen(p) + 1;
0148         successes += test(pat, p, expected);
0149         p += strlen(p) + 1;
0150         n++;
0151     }
0152 
0153     n -= successes;
0154     printk(message, successes, n);
0155 
0156     /* What's the errno for "kernel bug detected"?  Guess... */
0157     return n ? -ECANCELED : 0;
0158 }
0159 
0160 /* We need a dummy exit function to allow unload */
0161 static void __exit glob_fini(void) { }
0162 
0163 module_init(glob_init);
0164 module_exit(glob_fini);
0165 
0166 MODULE_DESCRIPTION("glob(7) matching tests");
0167 MODULE_LICENSE("Dual MIT/GPL");