11a89baa7Srsc // Simple grep. Only supports ^ . * $ operators. 21a89baa7Srsc 31a89baa7Srsc #include "types.h" 41a89baa7Srsc #include "stat.h" 51a89baa7Srsc #include "user.h" 61a89baa7Srsc 71a89baa7Srsc char buf[1024]; 81a89baa7Srsc int match(char*, char*); 91a89baa7Srsc 101a89baa7Srsc void 111a89baa7Srsc grep(char *pattern, int fd) 121a89baa7Srsc { 131a89baa7Srsc int n, m; 141a89baa7Srsc char *p, *q; 151a89baa7Srsc 161a89baa7Srsc m = 0; 17*7443b964SAustin Clements while((n = read(fd, buf+m, sizeof(buf)-m-1)) > 0){ 181a89baa7Srsc m += n; 19*7443b964SAustin Clements buf[m] = '\0'; 201a89baa7Srsc p = buf; 211a89baa7Srsc while((q = strchr(p, '\n')) != 0){ 221a89baa7Srsc *q = 0; 231a89baa7Srsc if(match(pattern, p)){ 241a89baa7Srsc *q = '\n'; 251a89baa7Srsc write(1, p, q+1 - p); 261a89baa7Srsc } 271a89baa7Srsc p = q+1; 281a89baa7Srsc } 291a89baa7Srsc if(p == buf) 301a89baa7Srsc m = 0; 311a89baa7Srsc if(m > 0){ 321a89baa7Srsc m -= p - buf; 331a89baa7Srsc memmove(buf, p, m); 341a89baa7Srsc } 351a89baa7Srsc } 361a89baa7Srsc } 371a89baa7Srsc 381a89baa7Srsc int 391a89baa7Srsc main(int argc, char *argv[]) 401a89baa7Srsc { 411a89baa7Srsc int fd, i; 421a89baa7Srsc char *pattern; 431a89baa7Srsc 441a89baa7Srsc if(argc <= 1){ 451a89baa7Srsc printf(2, "usage: grep pattern [file ...]\n"); 461a89baa7Srsc exit(); 471a89baa7Srsc } 481a89baa7Srsc pattern = argv[1]; 491a89baa7Srsc 501a89baa7Srsc if(argc <= 2){ 511a89baa7Srsc grep(pattern, 0); 521a89baa7Srsc exit(); 531a89baa7Srsc } 541a89baa7Srsc 551a89baa7Srsc for(i = 2; i < argc; i++){ 561a89baa7Srsc if((fd = open(argv[i], 0)) < 0){ 571a89baa7Srsc printf(1, "grep: cannot open %s\n", argv[i]); 581a89baa7Srsc exit(); 591a89baa7Srsc } 601a89baa7Srsc grep(pattern, fd); 611a89baa7Srsc close(fd); 621a89baa7Srsc } 631a89baa7Srsc exit(); 641a89baa7Srsc } 651a89baa7Srsc 661a89baa7Srsc // Regexp matcher from Kernighan & Pike, 671a89baa7Srsc // The Practice of Programming, Chapter 9. 681a89baa7Srsc 691a89baa7Srsc int matchhere(char*, char*); 701a89baa7Srsc int matchstar(int, char*, char*); 711a89baa7Srsc 721a89baa7Srsc int 731a89baa7Srsc match(char *re, char *text) 741a89baa7Srsc { 751a89baa7Srsc if(re[0] == '^') 761a89baa7Srsc return matchhere(re+1, text); 771a89baa7Srsc do{ // must look at empty string 781a89baa7Srsc if(matchhere(re, text)) 791a89baa7Srsc return 1; 801a89baa7Srsc }while(*text++ != '\0'); 811a89baa7Srsc return 0; 821a89baa7Srsc } 831a89baa7Srsc 841a89baa7Srsc // matchhere: search for re at beginning of text 851a89baa7Srsc int matchhere(char *re, char *text) 861a89baa7Srsc { 871a89baa7Srsc if(re[0] == '\0') 881a89baa7Srsc return 1; 891a89baa7Srsc if(re[1] == '*') 901a89baa7Srsc return matchstar(re[0], re+2, text); 911a89baa7Srsc if(re[0] == '$' && re[1] == '\0') 921a89baa7Srsc return *text == '\0'; 931a89baa7Srsc if(*text!='\0' && (re[0]=='.' || re[0]==*text)) 941a89baa7Srsc return matchhere(re+1, text+1); 951a89baa7Srsc return 0; 961a89baa7Srsc } 971a89baa7Srsc 981a89baa7Srsc // matchstar: search for c*re at beginning of text 991a89baa7Srsc int matchstar(int c, char *re, char *text) 1001a89baa7Srsc { 1011a89baa7Srsc do{ // a * matches zero or more instances 1021a89baa7Srsc if(matchhere(re, text)) 1031a89baa7Srsc return 1; 1041a89baa7Srsc }while(*text!='\0' && (*text++==c || c=='.')); 1051a89baa7Srsc return 0; 1061a89baa7Srsc } 1071a89baa7Srsc 108