aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toys/posix/grep.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/toys/posix/grep.c b/toys/posix/grep.c
index 5daccabc..3b3b674e 100644
--- a/toys/posix/grep.c
+++ b/toys/posix/grep.c
@@ -79,8 +79,11 @@ static void outline(char *line, char dash, char *name, long lcount, long bcount,
if (!line || (lcount && (toys.optflags&FLAG_n)))
printf("%ld%c", lcount, line ? dash : TT.outdelim);
if (bcount && (toys.optflags&FLAG_b)) printf("%ld%c", bcount-1, dash);
-// Support embedded NUL bytes in output
- if (line) xprintf("%.*s%c", trim, line, TT.outdelim);
+ if (line) {
+ // support embedded NUL bytes in output
+ fwrite(line, 1, trim, stdout);
+ xputc(TT.outdelim);
+ }
}
// Show matches in one file
@@ -234,15 +237,15 @@ static void do_grep(int fd, char *name)
else if (!(toys.optflags & FLAG_o)) {
while (dlb) {
struct double_list *dl = dlist_pop(&dlb);
+ unsigned *uu = (void *)(dl->data+((strlen(dl->data)+1)|3)+1);
- outline(dl->data, '-', name, lcount-before,
- *(unsigned *)(dl->data+((strlen(dl->data)+1)|3)+1)+1, -1);
+ outline(dl->data, '-', name, lcount-before, uu[0]+1, uu[1]);
free(dl->data);
free(dl);
before--;
}
- outline(line, ':', name, lcount, bcount, -1);
+ outline(line, ':', name, lcount, bcount, ulen);
if (TT.A) after = TT.A+1;
} else outline(start+matches.rm_so, ':', name, lcount, bcount,
matches.rm_eo-matches.rm_so);
@@ -258,14 +261,16 @@ static void do_grep(int fd, char *name)
int discard = (after || TT.B);
if (after && --after) {
- outline(line, '-', name, lcount, 0, -1);
+ outline(line, '-', name, lcount, 0, ulen);
discard = 0;
}
if (discard && TT.B) {
- if (FLAG(b)) {
- line = xrealloc(line, (ulen|3)+4);
- *(unsigned *)(line+(ulen|3)+1) = offset-len;
- }
+ unsigned *uu, ul = (ulen+1)|3;
+
+ line = xrealloc(line, ul+8);
+ uu = (void *)(line+ul+1);
+ uu[0] = offset-len;
+ uu[1] = ulen;
dlist_add(&dlb, line);
line = 0;
if (++before>TT.B) {
@@ -290,6 +295,12 @@ static void do_grep(int fd, char *name)
// loopfiles will also close the fd, but this frees an (opaque) struct.
fclose(file);
+ while (dlb) {
+ struct double_list *dl = dlist_pop(&dlb);
+
+ free(dl->data);
+ free(dl);
+ }
}
static void parse_regex(void)