grep.c revision 205b496e42ceb72bf0755fec4f4675a467c401e1
1e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake/* grep.c - print lines what match given regular expression 2e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake * 3e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake * Copyright 2013 CE Strake <strake888 at gmail.com> 4e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake * 5dad378bb17f1910014383bf196e87028e98d81d6Rob Landley * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html 6e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 7fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob LandleyUSE_GREP(NEWTOY(grep, "EFHabhinorsvwclqe*f*m#x[!wx][!EFw]", TOYFLAG_BIN)) 8dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob LandleyUSE_GREP(OLDTOY(egrep, grep, OPTSTR_grep, TOYFLAG_BIN)) 9dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob LandleyUSE_GREP(OLDTOY(fgrep, grep, OPTSTR_grep, TOYFLAG_BIN)) 10e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 11e999ca008416e3d41c1079bcb4d151b43c95dc3aStrakeconfig GREP 12e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake bool "grep" 13205b496e42ceb72bf0755fec4f4675a467c401e1Rob Landley default y 14e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake help 15dad378bb17f1910014383bf196e87028e98d81d6Rob Landley usage: grep [-EFivwcloqsHbhn] [-m MAX] [-e REGEX]... [-f REGFILE] [FILE]... 16f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley 17f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley Show lines matching regular expressions. If no -e, first argument is 18f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley regular expression to match. With no files (or "-" filename) read stdin. 19f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley Returns 0 if matched, 1 if no match found. 20f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley 21f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley -e Regex to match. (May be repeated.) 22f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley -f File containing regular expressions to match. 23f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley 24f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley match type: 25f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley -E extended regex syntax -F fixed (match literal string) 26fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley -i case insensitive -m stop after this many lines matched 27fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley -r recursive (on dir) -v invert match 28fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley -w whole word (implies -E) -x whole line 29f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley 30f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley display modes: (default: matched line) 31f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley -c count of matching lines -l show matching filenames 32f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley -o only matching part -q quiet (errors only) 33f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley -s silent (no error msg) 34f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley 35f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley prefix modes (default: filename if checking more than 1 file) 36f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley -H force filename -b byte offset of match 37f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley -h hide filename -n line number of match 38e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake*/ 39e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 40e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake#define FOR_grep 41e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake#include "toys.h" 42e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake#include <regex.h> 43e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 44e999ca008416e3d41c1079bcb4d151b43c95dc3aStrakeGLOBALS( 45dad378bb17f1910014383bf196e87028e98d81d6Rob Landley long m; 46dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley struct arg_list *f; 47dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley struct arg_list *e; 48dad378bb17f1910014383bf196e87028e98d81d6Rob Landley 49fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley struct arg_list *regex; 50e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake) 51e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 52f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landleystatic void do_grep(int fd, char *name) 53f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley{ 54dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley FILE *file = fdopen(fd, "r"); 55dad378bb17f1910014383bf196e87028e98d81d6Rob Landley long offset = 0; 56dad378bb17f1910014383bf196e87028e98d81d6Rob Landley int lcount = 0, mcount = 0, which = toys.optflags & FLAG_w ? 2 : 0; 57e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 5831f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley if (!fd) name = "(standard input)"; 5931f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley 60dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (!file) { 61dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley perror_msg("%s", name); 62dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley return; 63dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley } 64dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley 65e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake for (;;) { 66dad378bb17f1910014383bf196e87028e98d81d6Rob Landley char *line = 0, *start; 677b7b284ce4c1bd53d442927d9a570fcf84e0187cStrake regmatch_t matches[3]; 68dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley size_t unused; 69dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley long len; 70030970bd70e14849b0f2598bfa0982402fc7e2e7Rob Landley int mmatch = 0; 71e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 72dad378bb17f1910014383bf196e87028e98d81d6Rob Landley lcount++; 73dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (0 > (len = getline(&line, &unused, file))) break; 74dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (line[len-1] == '\n') line[len-1] = 0; 75dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley 76dad378bb17f1910014383bf196e87028e98d81d6Rob Landley start = line; 77e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 78dad378bb17f1910014383bf196e87028e98d81d6Rob Landley for (;;) 79f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley { 80dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley int rc = 0, skip = 0; 81dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley 82dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (toys.optflags & FLAG_F) { 83fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley struct arg_list *seek, fseek; 84dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley char *s = 0; 85dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley 86dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley for (seek = TT.e; seek; seek = seek->next) { 87fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley if (!*seek->arg) { 88fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley seek = &fseek; 89fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley fseek.arg = s = line; 90fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley break; 91fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley } 92dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (toys.optflags & FLAG_i) { 93dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley long ll = strlen(seek->arg);; 94dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley 95dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley // Alas, posix hasn't got strcasestr() 96dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley for (s = line; *s; s++) if (!strncasecmp(s, seek->arg, ll)) break; 97dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (!*s) s = 0; 98dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley } else s = strstr(line, seek->arg); 99dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (s) break; 100dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley } 101dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley 102dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (s) { 103dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley matches[which].rm_so = (s-line); 104dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley skip = matches[which].rm_eo = (s-line)+strlen(seek->arg); 105dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley } else rc = 1; 106dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley } else { 107dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley rc = regexec((regex_t *)toybuf, start, 3, matches, 108dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley start==line ? 0 : REG_NOTBOL); 109dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley skip = matches[which].rm_eo; 110dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley } 111dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley 112dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (toys.optflags & FLAG_x) 113dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (matches[which].rm_so || line[matches[which].rm_eo]) rc = 1; 114dad378bb17f1910014383bf196e87028e98d81d6Rob Landley 115dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (toys.optflags & FLAG_v) { 116dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (toys.optflags & FLAG_o) { 117dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (rc) skip = matches[which].rm_eo = strlen(start); 118dad378bb17f1910014383bf196e87028e98d81d6Rob Landley else if (!matches[which].rm_so) { 119dad378bb17f1910014383bf196e87028e98d81d6Rob Landley start += skip; 120dad378bb17f1910014383bf196e87028e98d81d6Rob Landley continue; 121dad378bb17f1910014383bf196e87028e98d81d6Rob Landley } else matches[which].rm_eo = matches[which].rm_so; 122dad378bb17f1910014383bf196e87028e98d81d6Rob Landley } else { 123dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (!rc) break; 124dad378bb17f1910014383bf196e87028e98d81d6Rob Landley matches[which].rm_eo = strlen(start); 125dad378bb17f1910014383bf196e87028e98d81d6Rob Landley } 126dad378bb17f1910014383bf196e87028e98d81d6Rob Landley matches[which].rm_so = 0; 127dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley } else if (rc) break; 128dad378bb17f1910014383bf196e87028e98d81d6Rob Landley 129030970bd70e14849b0f2598bfa0982402fc7e2e7Rob Landley mmatch++; 130dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (toys.optflags & FLAG_q) { 131dad378bb17f1910014383bf196e87028e98d81d6Rob Landley toys.exitval = 0; 132f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley xexit(); 133dad378bb17f1910014383bf196e87028e98d81d6Rob Landley } 134dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (toys.optflags & FLAG_l) { 135dad378bb17f1910014383bf196e87028e98d81d6Rob Landley printf("%s\n", name); 136dad378bb17f1910014383bf196e87028e98d81d6Rob Landley free(line); 137dad378bb17f1910014383bf196e87028e98d81d6Rob Landley fclose(file); 138e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake return; 139dad378bb17f1910014383bf196e87028e98d81d6Rob Landley } 140fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley if (toys.optflags & FLAG_o) 141fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley if (matches[which].rm_eo == matches[which].rm_so) 142fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley break; 143fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley 144dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (!(toys.optflags & FLAG_c)) { 145fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley if (toys.optflags & FLAG_H) printf("%s:", name); 146dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (toys.optflags & FLAG_n) printf("%d:", lcount); 147dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (toys.optflags & FLAG_b) 148dad378bb17f1910014383bf196e87028e98d81d6Rob Landley printf("%ld:", offset + (start-line) + 149dad378bb17f1910014383bf196e87028e98d81d6Rob Landley ((toys.optflags & FLAG_o) ? matches[which].rm_so : 0)); 150dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (!(toys.optflags & FLAG_o)) xputs(line); 151e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake else { 152dad378bb17f1910014383bf196e87028e98d81d6Rob Landley xprintf("%.*s\n", matches[which].rm_eo - matches[which].rm_so, 153dad378bb17f1910014383bf196e87028e98d81d6Rob Landley start + matches[which].rm_so); 154e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake } 155e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake } 156dad378bb17f1910014383bf196e87028e98d81d6Rob Landley 157dad378bb17f1910014383bf196e87028e98d81d6Rob Landley start += skip; 158dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (!(toys.optflags & FLAG_o) || !*start) break; 159e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake } 160dad378bb17f1910014383bf196e87028e98d81d6Rob Landley offset += len; 161e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 162dad378bb17f1910014383bf196e87028e98d81d6Rob Landley free(line); 163dad378bb17f1910014383bf196e87028e98d81d6Rob Landley 164030970bd70e14849b0f2598bfa0982402fc7e2e7Rob Landley if (mmatch) mcount++; 165dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if ((toys.optflags & FLAG_m) && mcount >= TT.m) break; 166dad378bb17f1910014383bf196e87028e98d81d6Rob Landley } 167e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 168dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (toys.optflags & FLAG_c) { 169fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley if (toys.optflags & FLAG_H) printf("%s:", name); 170dad378bb17f1910014383bf196e87028e98d81d6Rob Landley xprintf("%d\n", mcount); 171e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake } 172e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 173dad378bb17f1910014383bf196e87028e98d81d6Rob Landley // loopfiles will also close the fd, but this frees an (opaque) struct. 174dad378bb17f1910014383bf196e87028e98d81d6Rob Landley fclose(file); 175e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake} 176e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 177dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landleystatic void parse_regex(void) 178f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley{ 17931f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley struct arg_list *al, *new, *list = NULL; 180dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley long len = 0; 181dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley char *s, *ss; 182dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley 183dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley // Add all -f lines to -e list. (Yes, this is leaking allocation context for 184dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley // exit to free. Not supporting nofork for this command any time soon.) 18531f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley al = TT.f ? TT.f : TT.e; 18631f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley while (al) { 18731f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley if (TT.f) s = ss = xreadfile(al->arg); 18831f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley else s = ss = al->arg; 189dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley 190fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley do { 191dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley ss = strchr(s, '\n'); 19231f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley if (ss) *(ss++) = 0; 19331f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley new = xmalloc(sizeof(struct arg_list)); 19431f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley new->next = list; 19531f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley new->arg = s; 19631f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley list = new; 197dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley s = ss; 198fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley } while (ss && *s); 19931f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley al = al->next; 20031f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley if (!al && TT.f) { 20131f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley TT.f = 0; 20231f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley al = TT.e; 20331f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley } 204e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake } 20531f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley TT.e = list; 206f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley 207dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (!(toys.optflags & FLAG_F)) { 208dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley int w = toys.optflags & FLAG_w; 209fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley char *regstr; 210e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 21131f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley // Convert strings to one big regex 212dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (w) len = 36; 21331f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley for (al = TT.e; al; al = al->next) len += strlen(al->arg)+1; 214e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 215fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley regstr = s = xmalloc(len); 216dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (w) s = stpcpy(s, "(^|[^_[:alnum:]])("); 217dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley for (al = TT.e; al; al = al->next) { 218dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley s = stpcpy(s, al->arg); 21931f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley if (!(toys.optflags & FLAG_E)) *(s++) = '\\'; 220dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley *(s++) = '|'; 221e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake } 22231f07104445bc0c0cbc942d86ee9d31d08c344d8Rob Landley *(s-=(1+!(toys.optflags & FLAG_E))) = 0; 223dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (w) strcpy(s, ")($|[^_[:alnum:]])"); 224e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 225fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley w = regcomp((regex_t *)toybuf, regstr, 226dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley ((toys.optflags & FLAG_E) ? REG_EXTENDED : 0) | 227dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley ((toys.optflags & FLAG_i) ? REG_ICASE : 0)); 2287b7b284ce4c1bd53d442927d9a570fcf84e0187cStrake 229dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (w) { 230dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley regerror(w, (regex_t *)toybuf, toybuf+sizeof(regex_t), 231dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley sizeof(toybuf)-sizeof(regex_t)); 232dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley error_exit("bad REGEX: %s", toybuf); 233dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley } 234e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake } 235e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake} 236e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 237fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landleystatic int do_grep_r(struct dirtree *new) 238fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley{ 239fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley char *name; 240fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley 241fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley if (new->parent && !dirtree_notdotdot(new)) return 0; 242fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley if (S_ISDIR(new->st.st_mode)) return DIRTREE_RECURSE; 243fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley 244fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley // "grep -r onefile" doesn't show filenames, but "grep -r onedir" should. 245fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley if (new->parent && !(toys.optflags & FLAG_h)) toys.optflags |= FLAG_H; 246fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley 247fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley name = dirtree_path(new, 0); 248fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley do_grep(openat(dirtree_parentfd(new), new->name, 0), name); 249fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley free(name); 250fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley 251fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley return 0; 252fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley} 253fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley 254f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landleyvoid grep_main(void) 255f97eaf158aa0baf868f0b19d192f7d302c1484e9Rob Landley{ 256fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley char **ss; 257fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley 258dad378bb17f1910014383bf196e87028e98d81d6Rob Landley // Handle egrep and fgrep 259dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (*toys.which->name == 'e' || (toys.optflags & FLAG_w)) 260dad378bb17f1910014383bf196e87028e98d81d6Rob Landley toys.optflags |= FLAG_E; 261dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (*toys.which->name == 'f') toys.optflags |= FLAG_F; 2621fa68247345fa6e2cefe4fb4d88ef75f614b18c4M. Farkas-Dyck 263dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (!TT.e && !TT.f) { 264dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley if (!*toys.optargs) error_exit("no REGEX"); 265dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley TT.e = xzalloc(sizeof(struct arg_list)); 266dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley TT.e->arg = *(toys.optargs++); 267dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley toys.optc--; 268dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley } 269dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley 270dd2d23930241a30a8eb4f0fc9d70bc86c4a6cb6eRob Landley parse_regex(); 271e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 272fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley if (!(toys.optflags & FLAG_h) && toys.optc>1) toys.optflags |= FLAG_H; 273e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake 274174ba2bed2f33fe90926b08a3e9ec4e3ce7febabStrake toys.exitval = 1; 275dad378bb17f1910014383bf196e87028e98d81d6Rob Landley if (toys.optflags & FLAG_s) { 276dad378bb17f1910014383bf196e87028e98d81d6Rob Landley close(2); 277dad378bb17f1910014383bf196e87028e98d81d6Rob Landley xopen("/dev/null", O_RDWR); 278dad378bb17f1910014383bf196e87028e98d81d6Rob Landley } 279fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley 280fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley if (toys.optflags & FLAG_r) { 281fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley for (ss=toys.optargs; *ss; ss++) { 282fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley if (!strcmp(*ss, "-")) do_grep(0, *ss); 283fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley else dirtree_read(*ss, do_grep_r); 284fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley } 285fce85e9d287cef03777d3c2d97b2a0b43242ee21Rob Landley } else loopfiles_rw(toys.optargs, O_RDONLY, 0, 1, do_grep); 286e999ca008416e3d41c1079bcb4d151b43c95dc3aStrake} 287