Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #include <linux/glob.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * The only reason this code can be compiled as a module is because the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * ATA code that depends on it can be as well.  In practice, they're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * both usually compiled in and the module overhead goes away.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) MODULE_DESCRIPTION("glob(7) matching");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) MODULE_LICENSE("Dual MIT/GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * glob_match - Shell-style pattern matching, like !fnmatch(pat, str, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * @pat: Shell-style pattern to match, e.g. "*.[ch]".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * @str: String to match.  The pattern must match the entire string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * Perform shell-style glob matching, returning true (1) if the match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * succeeds, or false (0) if it fails.  Equivalent to !fnmatch(@pat, @str, 0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * Pattern metacharacters are ?, *, [ and \.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * (And, inside character classes, !, - and ].)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * This is small and simple implementation intended for device blacklists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * where a string is matched against a number of patterns.  Thus, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * does not preprocess the patterns.  It is non-recursive, and run-time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * is at most quadratic: strlen(@str)*strlen(@pat).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * An example of the worst case is glob_match("*aaaaa", "aaaaaaaaaa");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * it takes 6 passes over the pattern before matching the string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * Like !fnmatch(@pat, @str, 0) and unlike the shell, this does NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * treat / or leading . specially; it isn't actually used for pathnames.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * Note that according to glob(7) (and unlike bash), character classes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * are complemented by a leading !; this does not support the regex-style
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * [^a-z] syntax.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * An opening bracket without a matching close is matched literally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) bool __pure glob_match(char const *pat, char const *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	 * Backtrack to previous * on mismatch and retry starting one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	 * character later in the string.  Because * matches all characters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	 * (no exception for /), it can be easily proved that there's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	 * never a need to backtrack multiple levels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	char const *back_pat = NULL, *back_str = back_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	 * Loop over each token (character or class) in pat, matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	 * it against the remaining unmatched tail of str.  Return false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	 * on mismatch, or true after matching the trailing nul bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		unsigned char c = *str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		unsigned char d = *pat++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		switch (d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		case '?':	/* Wildcard: anything but nul */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			if (c == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 				return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		case '*':	/* Any-length wildcard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 			if (*pat == '\0')	/* Optimize trailing * case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 				return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 			back_pat = pat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 			back_str = --str;	/* Allow zero-length match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		case '[': {	/* Character class */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			bool match = false, inverted = (*pat == '!');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			char const *class = pat + inverted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			unsigned char a = *class++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			 * Iterate over each span in the character class.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 			 * A span is either a single character a, or a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 			 * range a-b.  The first span may begin with ']'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 				unsigned char b = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 				if (a == '\0')	/* Malformed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 					goto literal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 				if (class[0] == '-' && class[1] != ']') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 					b = class[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 					if (b == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 						goto literal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 					class += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 					/* Any special action if a > b? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 				match |= (a <= c && c <= b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			} while ((a = *class++) != ']');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			if (match == inverted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 				goto backtrack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			pat = class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		case '\\':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			d = *pat++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			/* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		default:	/* Literal character */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) literal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			if (c == d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 				if (d == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 					return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) backtrack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 			if (c == '\0' || !back_pat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 				return false;	/* No point continuing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			/* Try again from last *, one character later in str. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			pat = back_pat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			str = ++back_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) EXPORT_SYMBOL(glob_match);