123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- // Simple grep. Only supports ^ . * $ operators.
- #include "types.h"
- #include "stat.h"
- #include "user.h"
- char buf[1024];
- int match(char*, char*);
- void
- grep(char *pattern, int fd)
- {
- int n, m;
- char *p, *q;
-
- m = 0;
- while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){
- m += n;
- p = buf;
- while((q = strchr(p, '\n')) != 0){
- *q = 0;
- if(match(pattern, p)){
- *q = '\n';
- write(1, p, q+1 - p);
- }
- p = q+1;
- }
- if(p == buf)
- m = 0;
- if(m > 0){
- m -= p - buf;
- memmove(buf, p, m);
- }
- }
- }
- int
- main(int argc, char *argv[])
- {
- int fd, i;
- char *pattern;
-
- if(argc <= 1){
- printf(2, "usage: grep pattern [file ...]\n");
- exit();
- }
- pattern = argv[1];
-
- if(argc <= 2){
- grep(pattern, 0);
- exit();
- }
- for(i = 2; i < argc; i++){
- if((fd = open(argv[i], 0)) < 0){
- printf(1, "grep: cannot open %s\n", argv[i]);
- exit();
- }
- grep(pattern, fd);
- close(fd);
- }
- exit();
- }
- // Regexp matcher from Kernighan & Pike,
- // The Practice of Programming, Chapter 9.
- int matchhere(char*, char*);
- int matchstar(int, char*, char*);
- int
- match(char *re, char *text)
- {
- if(re[0] == '^')
- return matchhere(re+1, text);
- do{ // must look at empty string
- if(matchhere(re, text))
- return 1;
- }while(*text++ != '\0');
- return 0;
- }
- // matchhere: search for re at beginning of text
- int matchhere(char *re, char *text)
- {
- if(re[0] == '\0')
- return 1;
- if(re[1] == '*')
- return matchstar(re[0], re+2, text);
- if(re[0] == '$' && re[1] == '\0')
- return *text == '\0';
- if(*text!='\0' && (re[0]=='.' || re[0]==*text))
- return matchhere(re+1, text+1);
- return 0;
- }
- // matchstar: search for c*re at beginning of text
- int matchstar(int c, char *re, char *text)
- {
- do{ // a * matches zero or more instances
- if(matchhere(re, text))
- return 1;
- }while(*text!='\0' && (*text++==c || c=='.'));
- return 0;
- }
|