[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/busybox/src/shell/match.c b/ap/app/busybox/src/shell/match.c
new file mode 100644
index 0000000..fee3cf2
--- /dev/null
+++ b/ap/app/busybox/src/shell/match.c
@@ -0,0 +1,148 @@
+/*
+ * ##/%% variable matching code ripped out of ash shell for code sharing
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Kenneth Almquist.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ *
+ * Copyright (c) 1989, 1991, 1993, 1994
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
+ * was re-ported from NetBSD and debianized.
+ */
+#ifdef STANDALONE
+# include <stdbool.h>
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include <unistd.h>
+# define FAST_FUNC /* nothing */
+# define PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN /* nothing */
+# define POP_SAVED_FUNCTION_VISIBILITY /* nothing */
+#else
+# include "libbb.h"
+#endif
+#include <fnmatch.h>
+#include "match.h"
+
+char* FAST_FUNC scan_and_match(char *string, const char *pattern, unsigned flags)
+{
+	char *loc;
+	char *end;
+	unsigned len = strlen(string);
+	int early_exit;
+
+	/* We can stop the scan early only if the string part
+	 * we are matching against is shrinking, and the pattern has
+	 * an unquoted "star" at the corresponding end. There are two cases.
+	 * Case 1:
+	 * "qwerty" does not match against pattern "*zy",
+	 * no point in trying to match "werty", "erty" etc:
+	 */
+	early_exit = (flags == (SCAN_MOVE_FROM_LEFT + SCAN_MATCH_RIGHT_HALF) && pattern[0] == '*');
+
+	if (flags & SCAN_MOVE_FROM_LEFT) {
+		loc = string;
+		end = string + len + 1;
+	} else {
+		loc = string + len;
+		end = string - 1;
+		if (flags == (SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF)) {
+			/* Case 2:
+			 * "qwerty" does not match against pattern "qz*",
+			 * no point in trying to match "qwert", "qwer" etc:
+			 */
+			const char *p = pattern + strlen(pattern);
+			if (--p >= pattern && *p == '*') {
+				early_exit = 1;
+				while (--p >= pattern && *p == '\\')
+					early_exit ^= 1;
+			}
+		}
+	}
+
+	while (loc != end) {
+		char c;
+		int r;
+
+		c = *loc;
+		if (flags & SCAN_MATCH_LEFT_HALF) {
+			*loc = '\0';
+			r = fnmatch(pattern, string, 0);
+			*loc = c;
+		} else {
+			r = fnmatch(pattern, loc, 0);
+		}
+		if (r == 0) /* match found */
+			return loc;
+		if (early_exit) {
+#ifdef STANDALONE
+			printf("(early exit) ");
+#endif
+			break;
+		}
+
+		if (flags & SCAN_MOVE_FROM_LEFT) {
+			loc++;
+		} else {
+			loc--;
+		}
+	}
+	return NULL;
+}
+
+#ifdef STANDALONE
+int main(int argc, char *argv[])
+{
+	char *string;
+	char *op;
+	char *pattern;
+	char *loc;
+
+	setvbuf(stdout, NULL, _IONBF, 0);
+
+	if (!argv[1]) {
+		puts(
+			"Usage: match <test> [test...]\n\n"
+			"Where a <test> is the form: <string><op><match>\n"
+			"This is to test the shell ${var#val} expression type.\n\n"
+			"e.g. `match 'abc#a*'` -> bc"
+		);
+		return 1;
+	}
+
+	while (*++argv) {
+		size_t off;
+		unsigned scan_flags;
+
+		string = *argv;
+		off = strcspn(string, "#%");
+		if (!off) {
+			printf("invalid format\n");
+			continue;
+		}
+		op = string + off;
+		scan_flags = pick_scan(op[0], op[1]);
+
+		printf("'%s': flags:%x, ", string, scan_flags);
+		pattern = op + 1;
+		if (op[0] == op[1])
+			pattern++;
+		op[0] = '\0';
+
+		loc = scan_and_match(string, pattern, scan_flags);
+
+		if (scan_flags & SCAN_MATCH_LEFT_HALF) {
+			printf("'%s'\n", loc);
+		} else {
+			if (loc)
+				*loc = '\0';
+			printf("'%s'\n", string);
+		}
+	}
+
+	return 0;
+}
+#endif