[Toybox] [patch] add grep
James McMechan
james_mcmechan at hotmail.com
Tue Jul 9 11:41:40 PDT 2013
> Date: Mon, 8 Jul 2013 19:08:03 -0700
> From: idunham at lavabit.com
> To: strake888 at gmail.com
> CC: toybox at lists.landley.net
> Subject: Re: [Toybox] [patch] add grep
>
> On Sun, Jul 07, 2013 at 08:02:29PM -0500, Strake wrote:
>> # HG changeset patch
>> # User Strake
>> # Date 1373245375 18000
>> # Node ID 29e47cf402a5f81640c4b0a0e38d5f7741bc7ad6
>> # Parent f8db1f6ec4ab6972ee05126aae860e6ea104360e
>> add grep
>>
>> diff -r f8db1f6ec4ab -r 29e47cf402a5 toys/posix/grep.c
>> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
>> +++ b/toys/posix/grep.c Sun Jul 07 20:02:55 2013 -0500
>> @@ -0,0 +1,100 @@
>> +/* grep.c - print lines what match given regular expression
>> + *
>> + * Copyright 2013 CE Strake <strake888 at gmail.com>
>> + *
>> + * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/
>> + * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cmdbehav.html
>> +
>> +USE_GREP(NEWTOY(grep, "Einvclq", TOYFLAG_BIN))
>> +
>> +config GREP
>> + bool "grep"
>> + default y
>> + help
>> + usage: grep [-clq] [-Einv] RE [file...]
>
> This is not POSIX conformant yet, and would also break the kernel build.
>
I checked the kernel build (as of 3.8.13) by grepping for grep naturally...
It had grep fgrep egrep
and used flags -d -E -v -q -m -- -w -i -e -o -h -abo
which was a shorter list than I was expecting.
> grep must support multiple regexes:
> "Multiple -e and -f options shall be accepted by the grep utility."
> grep -e signals that the next argument is a regex.
> grep -f <file> means each line in <file> is a regex.
>
> Also you didn't implement -F (exact match), which is specified by POSIX.
>
> Practically speaking, you also will need to support
> grep -h (which outputs only the matching line without the filename)
> This is required by the kernel build process.
> And as far as I can tell, you don't have a switch to suppress filename
> when only one file is specified.
>
> grep -r is frequently used, and that's trivial to implement with dirtree_*.
>
>> + modes:
>> + default: print lines from each file what match regular expression RE.
>> + -c: print the number of matching lines in each file.
>> + -l: print all matching file names.
>> + -q: print nil; quit with code 0 when match found.
>> +
>> + flags:
>> + -E: extended RE syntax
>> + -i: case insensitive
>> + -n: print line numbers
>> + -v: invert match
>> +*/
>> +
>> +#define FOR_grep
>> +#include "toys.h"
>> +#include <regex.h>
>> +#include <err.h>
>> +
>> +/* could be in GLOBALS but so need initialization code */
>> +char mode = 0;
>> +int c = 1;
>> +
>> +regex_t re; /* fails in GLOBALS */
>> +
>> +static void do_grep (int fd, char *name) {
>> + int n = 0, nMatch = 0;
>> + size_t l;
>> + char *x;
>> + FILE *f;
>> +
>> + f = fdopen (fd, "r");
>> + if (!f) err (2, "failed to open %s", name);
>> +
>> + x = 0;
>> + for (;;) {
>> + if (getline (&x, &l, f) < 0) {
>> + if (feof (f)) break;
>> + err (2, "failed to read");
>> + }
>> + n++; /* start at 1 */
>> +
>> + if (regexec (&re, x, 0, 0, 0) == 0) {
>> + c = 0; nMatch++;
>> + switch (mode) {
>> + case 'q':
>> + exit (0);
>> + case 'l':
>> + printf ("%s\n", name);
>> + goto end;
>> + case 'c':
>> + break;
>> + default:
>> + printf ("%s:", name);
>> + if (toys.optflags & FLAG_n) printf ("%d:", n);
>> + fputs (x, stdout);
>> + }
>> + }
>> + }
>> +
>> + if (mode == 'c') printf ("%s:%d\n", name, nMatch);
>> +
>> +end:
>> + free (x);
>> + fclose (f);
>> +}
>> +
>> +void grep_main (void) {
>> + if (toys.optc < 1) errx (2, "no RE");
>> +
>> + if (regcomp (&re, toys.optargs[0],
>> + REG_NOSUB |
>> + (toys.optflags & FLAG_E ? REG_EXTENDED : 0) |
>> + (toys.optflags & FLAG_i ? REG_ICASE : 0)) != 0) {
>> + errx (2, "bad RE");
>> + }
>> +
>> + if (toys.optflags & FLAG_c) mode = 'c';
>> + if (toys.optflags & FLAG_l) mode = 'l';
>> + if (toys.optflags & FLAG_q) mode = 'q';
>> +
>> + if (toys.optc> 1) loopfiles (toys.optargs + 1, do_grep);
>> + else do_grep (0, "-");
>> +
>> + exit (c);
>> +}
>
> _______________________________________________
> Toybox mailing list
> Toybox at lists.landley.net
> http://lists.landley.net/listinfo.cgi/toybox-landley.net
1373395300.0
More information about the Toybox
mailing list