Mercurial > hg > CbC > CbC_xv6
comparison src/usr/grep.c @ 0:83c23a36980d
Init
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 26 May 2017 23:11:05 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:83c23a36980d |
---|---|
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 |