diff options
author | Mike Frysinger | 2009-04-07 06:03:22 +0000 |
---|---|---|
committer | Mike Frysinger | 2009-04-07 06:03:22 +0000 |
commit | a4f331d3c3ea5b358613992a48556cc9cbfdf139 (patch) | |
tree | 316143ec21a1efd2eb7e135121134c0b8b86221e /shell/match.c | |
parent | 6c9be7f4518bf5594f5b9aaf981ed5dcc4a6939c (diff) | |
download | busybox-a4f331d3c3ea5b358613992a48556cc9cbfdf139.zip busybox-a4f331d3c3ea5b358613992a48556cc9cbfdf139.tar.gz |
implement support for parameter substitution via #/% operators
Diffstat (limited to 'shell/match.c')
-rw-r--r-- | shell/match.c | 141 |
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 |