1/* 2 * ##/%% variable matching code ripped out of ash shell for code sharing 3 * 4 * This code is derived from software contributed to Berkeley by 5 * Kenneth Almquist. 6 * 7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 8 * 9 * Copyright (c) 1989, 1991, 1993, 1994 10 * The Regents of the University of California. All rights reserved. 11 * 12 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au> 13 * was re-ported from NetBSD and debianized. 14 */ 15#ifdef STANDALONE 16# include <stdbool.h> 17# include <stdio.h> 18# include <stdlib.h> 19# include <string.h> 20# include <unistd.h> 21#else 22# include "libbb.h" 23#endif 24#include <fnmatch.h> 25#include "match.h" 26 27#define pmatch(a, b) !fnmatch((a), (b), 0) 28 29char *scanleft(char *string, char *pattern, bool match_at_left) 30{ 31 char c; 32 char *loc = string; 33 34 do { 35 int match; 36 const char *s; 37 38 c = *loc; 39 if (match_at_left) { 40 *loc = '\0'; 41 s = string; 42 } else 43 s = loc; 44 match = pmatch(pattern, s); 45 *loc = c; 46 47 if (match) 48 return loc; 49 50 loc++; 51 } while (c); 52 53 return NULL; 54} 55 56char *scanright(char *string, char *pattern, bool match_at_left) 57{ 58 char c; 59 char *loc = string + strlen(string); 60 61 while (loc >= string) { 62 int match; 63 const char *s; 64 65 c = *loc; 66 if (match_at_left) { 67 *loc = '\0'; 68 s = string; 69 } else 70 s = loc; 71 match = pmatch(pattern, s); 72 *loc = c; 73 74 if (match) 75 return loc; 76 77 loc--; 78 } 79 80 return NULL; 81} 82 83#ifdef STANDALONE 84int main(int argc, char *argv[]) 85{ 86 char *string; 87 char *op; 88 char *pattern; 89 bool match_at_left; 90 char *loc; 91 92 int i; 93 94 if (argc == 1) { 95 puts( 96 "Usage: match <test> [test...]\n\n" 97 "Where a <test> is the form: <string><op><match>\n" 98 "This is to test the shell ${var#val} expression type.\n\n" 99 "e.g. `match 'abc#a*'` -> bc" 100 ); 101 return 1; 102 } 103 104 for (i = 1; i < argc; ++i) { 105 size_t off; 106 scan_t scan; 107 108 printf("'%s': ", argv[i]); 109 110 string = strdup(argv[i]); 111 off = strcspn(string, "#%"); 112 if (!off) { 113 printf("invalid format\n"); 114 free(string); 115 continue; 116 } 117 op = string + off; 118 scan = pick_scan(op[0], op[1], &match_at_left); 119 pattern = op + 1; 120 if (op[0] == op[1]) 121 op[1] = '\0', ++pattern; 122 op[0] = '\0'; 123 124 loc = scan(string, pattern, match_at_left); 125 126 if (match_at_left) { 127 printf("'%s'\n", loc); 128 } else { 129 *loc = '\0'; 130 printf("'%s'\n", string); 131 } 132 133 free(string); 134 } 135 136 return 0; 137} 138#endif 139