aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2018-12-17 21:27:25 -0600
committerRob Landley <rob@landley.net>2018-12-17 21:27:25 -0600
commit84e22115a55f82c84b43807a690ac5904c616317 (patch)
treef70f589915616cbc913483365eecd8291d2d0a36
parentc1a22bbca751bc6ae7ffb8d7cfaf5100306e897b (diff)
downloadtoybox-84e22115a55f82c84b43807a690ac5904c616317.tar.gz
A couple more grep tests, and slightly use dlist_terminate() for the loops.
-rw-r--r--tests/grep.test3
-rw-r--r--toys/posix/grep.c31
2 files changed, 20 insertions, 14 deletions
diff --git a/tests/grep.test b/tests/grep.test
index 21cd8bbb..05288983 100644
--- a/tests/grep.test
+++ b/tests/grep.test
@@ -151,3 +151,6 @@ testing "explicit BRE |" "grep -e 'uno|dos'" "uno|dos\n" \
"" "uno\ndos\nuno|dos\n"
testing "explicit ERE |" "grep -E 'uno|dos'" "uno\ndos\nuno|dos\n" \
"" "uno\ndos\nuno|dos\n"
+
+testing "" "grep -o -e iss -e ipp" "iss\niss\nipp\n" "" "mississippi"
+testing "" "grep -o -e gum -e rgu" "rgu\n" "" "argument"
diff --git a/toys/posix/grep.c b/toys/posix/grep.c
index 138a948f..f1084830 100644
--- a/toys/posix/grep.c
+++ b/toys/posix/grep.c
@@ -131,7 +131,6 @@ static void do_grep(int fd, char *name)
// Loop through lines of input
for (;;) {
char *line = 0, *start;
- regmatch_t *mm = (void *)toybuf;
struct reg *shoe;
size_t ulen;
long len;
@@ -147,13 +146,12 @@ static void do_grep(int fd, char *name)
// Prepare for next line
start = line;
- if (TT.reg) for (shoe = (void *)TT.reg;;) {
+ if (TT.reg) for (shoe = (void *)TT.reg; shoe; shoe = shoe->next)
shoe->rc = 0;
- if ((shoe = shoe->next) == (void *)TT.reg) break;
- }
// Loop to handle multiple matches in same line
do {
+ regmatch_t *mm = (void *)toybuf;
int rc, skip = 0;
// Handle "fixed" (literal) matches
@@ -184,24 +182,27 @@ static void do_grep(int fd, char *name)
// Handle regex matches
} else {
- mm->rm_so = mm->rm_eo = 0;
+ mm->rm_so = INT_MAX;
rc = 1;
- for (shoe = (void *)TT.reg;;) {
+ for (shoe = (void *)TT.reg; shoe; shoe = shoe->next) {
// Do we need to re-check this regex?
- if (!shoe->rc && (!matched || (shoe->m.rm_so -= baseline)<0))
- shoe->rc = regexec0(&shoe->r, start, ulen-(start-line), 1,
- &shoe->m, start==line ? 0 : REG_NOTBOL);
+ if (!shoe->rc) {
+ shoe->m.rm_so -= baseline;
+ shoe->m.rm_eo -= baseline;
+ if (!matched || shoe->m.rm_so<0)
+ shoe->rc = regexec0(&shoe->r, start, ulen-(start-line), 1,
+ &shoe->m, start==line ? 0 : REG_NOTBOL);
+ }
// If we got a match, is it a _better_ match?
- if (!shoe->rc && (mm->rm_so < shoe->m.rm_so ||
- (mm->rm_so == shoe->m.rm_so && shoe->m.rm_eo >= skip)))
+ if (!shoe->rc && (shoe->m.rm_so < mm->rm_so ||
+ (shoe->m.rm_so == mm->rm_so && shoe->m.rm_eo >= skip)))
{
mm = &shoe->m;
skip = mm->rm_eo;
rc = 0;
}
- if ((shoe = shoe->next) == (void *)TT.reg) break;
}
baseline = skip;
}
@@ -373,9 +374,10 @@ static void parse_regex(void)
// Convert regex list
for (al = TT.e; al; al = al->next) {
- struct reg *shoe = xmalloc(sizeof(struct reg));
+ struct reg *shoe;
- dlist_add_nomalloc(&TT.reg, (void *)shoe);
+ if (FLAG(o) && !*al->arg) continue;
+ dlist_add_nomalloc(&TT.reg, (void *)(shoe = xmalloc(sizeof(struct reg))));
i = regcomp(&shoe->r, al->arg,
(REG_EXTENDED*!!FLAG(E)) | (REG_ICASE*!!FLAG(i)));
if (i) {
@@ -383,6 +385,7 @@ static void parse_regex(void)
error_exit("bad REGEX '%s': %s", al->arg, toybuf);
}
}
+ dlist_terminate(TT.reg);
}
}