implement support for parameter substitution via #/% operators
This commit is contained in:
141
shell/match.c
Normal file
141
shell/match.c
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* ##/%% 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.
|
||||
*
|
||||
* Original BSD copyright notice is retained at the end of this file.
|
||||
*/
|
||||
|
||||
#ifdef STANDALONE
|
||||
# include <stdbool.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <unistd.h>
|
||||
#else
|
||||
# include "busybox.h"
|
||||
#endif
|
||||
#include <fnmatch.h>
|
||||
#include "match.h"
|
||||
|
||||
#define pmatch(a, b) !fnmatch((a), (b), 0)
|
||||
|
||||
char *scanleft(char *string, char *pattern, bool zero)
|
||||
{
|
||||
char c;
|
||||
char *loc = string;
|
||||
|
||||
do {
|
||||
int match;
|
||||
const char *s;
|
||||
|
||||
c = *loc;
|
||||
if (zero) {
|
||||
*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 zero)
|
||||
{
|
||||
char c;
|
||||
char *loc = string + strlen(string);
|
||||
|
||||
while (loc >= string) {
|
||||
int match;
|
||||
const char *s;
|
||||
|
||||
c = *loc;
|
||||
if (zero) {
|
||||
*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 zero;
|
||||
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], &zero);
|
||||
pattern = op + 1;
|
||||
if (op[0] == op[1])
|
||||
op[1] = '\0', ++pattern;
|
||||
op[0] = '\0';
|
||||
|
||||
loc = scan(string, pattern, zero);
|
||||
|
||||
if (zero) {
|
||||
printf("'%s'\n", loc);
|
||||
} else {
|
||||
*loc = '\0';
|
||||
printf("'%s'\n", string);
|
||||
}
|
||||
|
||||
free(string);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user