0ef64bdb40
This change retains "or later" state! No licensing _changes_ here, only form is adjusted (article, space between "GPL" and "v2" and so on). Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
139 lines
2.3 KiB
C
139 lines
2.3 KiB
C
/*
|
|
* ##/%% variable matching code ripped out of ash shell for code sharing
|
|
*
|
|
* This code is derived from software contributed to Berkeley by
|
|
* Kenneth Almquist.
|
|
*
|
|
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
|
*
|
|
* 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.
|
|
*/
|
|
#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
|