blob: fb6a38ef118be98714fe459eb635235358a335c0 [file] [log] [blame]
Mike Frysingera4f331d2009-04-07 06:03:22 +00001/*
2 * ##/%% variable matching code ripped out of ash shell for code sharing
3 *
Denys Vlasenko73067272010-01-12 22:11:24 +01004 * 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 *
Mike Frysingera4f331d2009-04-07 06:03:22 +00009 * 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.
Mike Frysingera4f331d2009-04-07 06:03:22 +000014 */
Mike Frysingera4f331d2009-04-07 06:03:22 +000015#ifdef STANDALONE
16# include <stdbool.h>
17# include <stdio.h>
18# include <stdlib.h>
19# include <string.h>
20# include <unistd.h>
21#else
Denis Vlasenko1943aec2009-04-09 14:15:57 +000022# include "libbb.h"
Mike Frysingera4f331d2009-04-07 06:03:22 +000023#endif
24#include <fnmatch.h>
25#include "match.h"
26
27#define pmatch(a, b) !fnmatch((a), (b), 0)
28
Denis Vlasenko5b7589e2009-04-26 11:25:19 +000029char *scanleft(char *string, char *pattern, bool match_at_left)
Mike Frysingera4f331d2009-04-07 06:03:22 +000030{
31 char c;
32 char *loc = string;
33
34 do {
35 int match;
36 const char *s;
37
38 c = *loc;
Denis Vlasenko5b7589e2009-04-26 11:25:19 +000039 if (match_at_left) {
Mike Frysingera4f331d2009-04-07 06:03:22 +000040 *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
Denis Vlasenko5b7589e2009-04-26 11:25:19 +000056char *scanright(char *string, char *pattern, bool match_at_left)
Mike Frysingera4f331d2009-04-07 06:03:22 +000057{
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;
Denis Vlasenko5b7589e2009-04-26 11:25:19 +000066 if (match_at_left) {
Mike Frysingera4f331d2009-04-07 06:03:22 +000067 *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;
Denis Vlasenko5b7589e2009-04-26 11:25:19 +000089 bool match_at_left;
Mike Frysingera4f331d2009-04-07 06:03:22 +000090 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;
Denis Vlasenko5b7589e2009-04-26 11:25:19 +0000118 scan = pick_scan(op[0], op[1], &match_at_left);
Mike Frysingera4f331d2009-04-07 06:03:22 +0000119 pattern = op + 1;
120 if (op[0] == op[1])
121 op[1] = '\0', ++pattern;
122 op[0] = '\0';
123
Denis Vlasenko5b7589e2009-04-26 11:25:19 +0000124 loc = scan(string, pattern, match_at_left);
Mike Frysingera4f331d2009-04-07 06:03:22 +0000125
Denis Vlasenko5b7589e2009-04-26 11:25:19 +0000126 if (match_at_left) {
Mike Frysingera4f331d2009-04-07 06:03:22 +0000127 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