/* * ##/%% 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. */ #ifdef STANDALONE # include <stdbool.h> # include <stdio.h> # include <stdlib.h> # include <string.h> # include <unistd.h> #else # include "libbb.h" #endif #include <fnmatch.h> #include "match.h" #define pmatch(a, b) !fnmatch((a), (b), 0) char *scanleft(char *string, char *pattern, bool match_at_left) { char c; char *loc = string; do { int match; const char *s; c = *loc; if (match_at_left) { *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 match_at_left) { char c; char *loc = string + strlen(string); while (loc >= string) { int match; const char *s; c = *loc; if (match_at_left) { *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 match_at_left; 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], &match_at_left); pattern = op + 1; if (op[0] == op[1]) op[1] = '\0', ++pattern; op[0] = '\0'; loc = scan(string, pattern, match_at_left); if (match_at_left) { printf("'%s'\n", loc); } else { *loc = '\0'; printf("'%s'\n", string); } free(string); } return 0; } #endif