comparison uprogs/grep.c @ 0:c450faca55f4

Init
author Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp>
date Sun, 22 Oct 2017 18:25:39 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:c450faca55f4
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