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