2 * ##/%% variable matching code ripped out of ash shell for code sharing
4 * This code is derived from software contributed to Berkeley by
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
9 * Copyright (c) 1989, 1991, 1993, 1994
10 * The Regents of the University of California. All rights reserved.
12 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
13 * was re-ported from NetBSD and debianized.
21 # define FAST_FUNC /* nothing */
22 # define PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN /* nothing */
23 # define POP_SAVED_FUNCTION_VISIBILITY /* nothing */
30 #define pmatch(a, b) !fnmatch((a), (b), 0)
32 char* FAST_FUNC scan_and_match(char *string, const char *pattern, unsigned flags)
36 unsigned len = strlen(string);
39 /* We can stop the scan early only if the string part
40 * we are matching against is shrinking, and the pattern has
41 * an unquoted "star" at the corresponding end. There are two cases.
43 * "qwerty" does not match against pattern "*zy",
44 * no point in trying to match "werty", "erty" etc:
46 early_exit = (flags == (SCAN_MOVE_FROM_LEFT + SCAN_MATCH_RIGHT_HALF) && pattern[0] == '*');
48 if (flags & SCAN_MOVE_FROM_LEFT) {
50 end = string + len + 1;
54 if (flags == (SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF)) {
56 * "qwerty" does not match against pattern "qz*",
57 * no point in trying to match "qwert", "qwer" etc:
59 const char *p = pattern + strlen(pattern);
60 if (--p >= pattern && *p == '*') {
62 while (--p >= pattern && *p == '\\')
73 if (flags & SCAN_MATCH_LEFT_HALF) {
75 match = pmatch(pattern, string);
78 match = pmatch(pattern, loc);
84 printf("(early exit) ");
89 if (flags & SCAN_MOVE_FROM_LEFT) {
99 int main(int argc, char *argv[])
106 setvbuf(stdout, NULL, _IONBF, 0);
110 "Usage: match <test> [test...]\n\n"
111 "Where a <test> is the form: <string><op><match>\n"
112 "This is to test the shell ${var#val} expression type.\n\n"
113 "e.g. `match 'abc#a*'` -> bc"
123 off = strcspn(string, "#%");
125 printf("invalid format\n");
129 scan_flags = pick_scan(op[0], op[1]);
131 printf("'%s': flags:%x, ", string, scan_flags);
137 loc = scan_and_match(string, pattern, scan_flags);
139 if (scan_flags & SCAN_MATCH_LEFT_HALF) {
140 printf("'%s'\n", loc);
144 printf("'%s'\n", string);