summaryrefslogtreecommitdiff
path: root/shell/match.c
diff options
context:
space:
mode:
authorMike Frysinger2009-04-07 06:03:22 +0000
committerMike Frysinger2009-04-07 06:03:22 +0000
commita4f331d3c3ea5b358613992a48556cc9cbfdf139 (patch)
tree316143ec21a1efd2eb7e135121134c0b8b86221e /shell/match.c
parent6c9be7f4518bf5594f5b9aaf981ed5dcc4a6939c (diff)
downloadbusybox-a4f331d3c3ea5b358613992a48556cc9cbfdf139.zip
busybox-a4f331d3c3ea5b358613992a48556cc9cbfdf139.tar.gz
implement support for parameter substitution via #/% operators
Diffstat (limited to 'shell/match.c')
-rw-r--r--shell/match.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/shell/match.c b/shell/match.c
new file mode 100644
index 0000000..0810fd8
--- /dev/null
+++ b/shell/match.c
@@ -0,0 +1,141 @@
+/*
+ * ##/%% variable matching code ripped out of ash shell for code sharing
+ *
+ * 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.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Kenneth Almquist.
+ *
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+ *
+ * Original BSD copyright notice is retained at the end of this file.
+ */
+
+#ifdef STANDALONE
+# include <stdbool.h>
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include <unistd.h>
+#else
+# include "busybox.h"
+#endif
+#include <fnmatch.h>
+#include "match.h"
+
+#define pmatch(a, b) !fnmatch((a), (b), 0)
+
+char *scanleft(char *string, char *pattern, bool zero)
+{
+ char c;
+ char *loc = string;
+
+ do {
+ int match;
+ const char *s;
+
+ c = *loc;
+ if (zero) {
+ *loc = '\0';
+ s = string;
+ } else
+ s = loc;
+ match = pmatch(pattern, s);
+ *loc = c;
+
+ if (match)
+ return loc;
+
+ loc++;
+ } while (c);
+
+ return NULL;
+}
+
+char *scanright(char *string, char *pattern, bool zero)
+{
+ char c;
+ char *loc = string + strlen(string);
+
+ while (loc >= string) {
+ int match;
+ const char *s;
+
+ c = *loc;
+ if (zero) {
+ *loc = '\0';
+ s = string;
+ } else
+ s = loc;
+ match = pmatch(pattern, s);
+ *loc = c;
+
+ if (match)
+ return loc;
+
+ loc--;
+ }
+
+ return NULL;
+}
+
+#ifdef STANDALONE
+int main(int argc, char *argv[])
+{
+ char *string;
+ char *op;
+ char *pattern;
+ bool zero;
+ char *loc;
+
+ int i;
+
+ if (argc == 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;
+ }
+
+ for (i = 1; i < argc; ++i) {
+ size_t off;
+ scan_t scan;
+
+ printf("'%s': ", argv[i]);
+
+ string = strdup(argv[i]);
+ off = strcspn(string, "#%");
+ if (!off) {
+ printf("invalid format\n");
+ free(string);
+ continue;
+ }
+ op = string + off;
+ scan = pick_scan(op[0], op[1], &zero);
+ pattern = op + 1;
+ if (op[0] == op[1])
+ op[1] = '\0', ++pattern;
+ op[0] = '\0';
+
+ loc = scan(string, pattern, zero);
+
+ if (zero) {
+ printf("'%s'\n", loc);
+ } else {
+ *loc = '\0';
+ printf("'%s'\n", string);
+ }
+
+ free(string);
+ }
+
+ return 0;
+}
+#endif