xv6

port of xv6 to x86-64
git clone http://frotz.net/git/xv6.git
Log | Files | Refs | README | LICENSE

grep.c (1939B)


      1 // Simple grep.  Only supports ^ . * $ operators.
      2 
      3 #include "types.h"
      4 #include "stat.h"
      5 #include "user.h"
      6 
      7 char buf[1024];
      8 int match(char*, char*);
      9 
     10 void
     11 grep(char *pattern, int fd)
     12 {
     13   int n, m;
     14   char *p, *q;
     15   
     16   m = 0;
     17   while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){
     18     m += n;
     19     p = buf;
     20     while((q = strchr(p, '\n')) != 0){
     21       *q = 0;
     22       if(match(pattern, p)){
     23         *q = '\n';
     24         write(1, p, q+1 - p);
     25       }
     26       p = q+1;
     27     }
     28     if(p == buf)
     29       m = 0;
     30     if(m > 0){
     31       m -= p - buf;
     32       memmove(buf, p, m);
     33     }
     34   }
     35 }
     36 
     37 int
     38 main(int argc, char *argv[])
     39 {
     40   int fd, i;
     41   char *pattern;
     42   
     43   if(argc <= 1){
     44     printf(2, "usage: grep pattern [file ...]\n");
     45     exit();
     46   }
     47   pattern = argv[1];
     48   
     49   if(argc <= 2){
     50     grep(pattern, 0);
     51     exit();
     52   }
     53 
     54   for(i = 2; i < argc; i++){
     55     if((fd = open(argv[i], 0)) < 0){
     56       printf(1, "grep: cannot open %s\n", argv[i]);
     57       exit();
     58     }
     59     grep(pattern, fd);
     60     close(fd);
     61   }
     62   exit();
     63 }
     64 
     65 // Regexp matcher from Kernighan & Pike,
     66 // The Practice of Programming, Chapter 9.
     67 
     68 int matchhere(char*, char*);
     69 int matchstar(int, char*, char*);
     70 
     71 int
     72 match(char *re, char *text)
     73 {
     74   if(re[0] == '^')
     75     return matchhere(re+1, text);
     76   do{  // must look at empty string
     77     if(matchhere(re, text))
     78       return 1;
     79   }while(*text++ != '\0');
     80   return 0;
     81 }
     82 
     83 // matchhere: search for re at beginning of text
     84 int matchhere(char *re, char *text)
     85 {
     86   if(re[0] == '\0')
     87     return 1;
     88   if(re[1] == '*')
     89     return matchstar(re[0], re+2, text);
     90   if(re[0] == '$' && re[1] == '\0')
     91     return *text == '\0';
     92   if(*text!='\0' && (re[0]=='.' || re[0]==*text))
     93     return matchhere(re+1, text+1);
     94   return 0;
     95 }
     96 
     97 // matchstar: search for c*re at beginning of text
     98 int matchstar(int c, char *re, char *text)
     99 {
    100   do{  // a * matches zero or more instances
    101     if(matchhere(re, text))
    102       return 1;
    103   }while(*text!='\0' && (*text++==c || c=='.'));
    104   return 0;
    105 }
    106