Mercurial > hg > Members > nobuyasu > test
comparison regen/src/grep/grep_jobs.cbc.c~ @ 12:a6f51c76dea8
add grep.c
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 28 Jun 2011 16:25:37 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
11:1e0cd7fade8b | 12:a6f51c76dea8 |
---|---|
1 #include <stdio.h> | |
2 #include <stdlib.h> | |
3 #include <sys/mman.h> | |
4 #include <sys/types.h> | |
5 #include <sys/stat.h> | |
6 #include <fcntl.h> | |
7 #include <unistd.h> | |
8 #include <string.h> | |
9 #include <setjmp.h> | |
10 | |
11 typedef unsigned char UCHAR; | |
12 typedef unsigned char* UCHARP; | |
13 | |
14 typedef enum BOOL { | |
15 FALSE = 0, | |
16 TRUE = 1 | |
17 } BOOL; | |
18 | |
19 typedef struct ENV { | |
20 BOOL print_count; | |
21 BOOL print_filename; | |
22 int count; | |
23 char *filename; | |
24 jmp_buf *ret; | |
25 } *ENVP; | |
26 | |
27 __code filter(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); | |
28 __code predict(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); | |
29 __code reject(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); | |
30 __code accept(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); | |
31 void s0(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); | |
32 __code _s0(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); | |
33 #define __REGEX__ "h.c" | |
34 | |
35 UCHARP get_line_beg(UCHARP p, UCHARP beg) { | |
36 while(p > beg) { | |
37 if ((*--p) == '\n') return p+1; | |
38 } | |
39 return beg; | |
40 } | |
41 | |
42 void print_line(UCHARP beg, UCHARP end) { | |
43 fwrite(beg, sizeof(char), (end - beg + 1), stdout); | |
44 } | |
45 | |
46 void grep(int fd, ENVP env) { | |
47 caddr_t file_mmap; | |
48 UCHARP buf, end, beg; | |
49 off_t size; | |
50 struct stat sb; | |
51 | |
52 if (fstat(fd, &sb)) { | |
53 fprintf(stderr, "can't fstat %s\n", env->filename); | |
54 exit(0); | |
55 } | |
56 | |
57 size = sb.st_size; | |
58 file_mmap = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, (off_t)0); | |
59 | |
60 if (file_mmap == (caddr_t)-1) { | |
61 fprintf(stderr, "can't mmap %s\n", env->filename); | |
62 exit(0); | |
63 } | |
64 | |
65 beg = buf = (UCHARP) file_mmap; | |
66 end = beg + size - 1; | |
67 env->count = 0; | |
68 | |
69 s0(beg, beg, end, env); | |
70 | |
71 munmap(file_mmap, size); | |
72 return; | |
73 } | |
74 | |
75 void stdingrep(ENVP env) { | |
76 char buf_[BUFSIZ]; | |
77 UCHARP buf, beg, end; | |
78 buf = beg = (UCHARP) buf_; | |
79 | |
80 while (fgets(buf_, BUFSIZ, stdin) != NULL) { | |
81 env->count = 0; | |
82 end = buf + strlen(buf_) - 1; | |
83 s0(beg, buf, end, env); | |
84 } | |
85 } | |
86 | |
87 int main(int argc, char* argv[]) { | |
88 int i, fd, opt, with_filename = 0; | |
89 | |
90 ENVP env = (ENVP)calloc(sizeof(ENVP), 1); | |
91 | |
92 while ((opt=getopt(argc, argv, "chH")) != -1) { | |
93 switch (opt) { | |
94 case 'c': | |
95 env->print_count = 1; | |
96 break; | |
97 case 'h': | |
98 with_filename = -1; | |
99 break; | |
100 case 'H': | |
101 with_filename = 1; | |
102 break; | |
103 default: | |
104 fprintf(stderr, "invalid option."); | |
105 exit(0); | |
106 } | |
107 } | |
108 | |
109 if (optind == argc) { | |
110 if (with_filename) { | |
111 /* handle -h/-H as help */ | |
112 printf("grep pattern: %s\n", __REGEX__); | |
113 exit(1); | |
114 } else { | |
115 stdingrep(env); | |
116 } | |
117 } else { | |
118 switch (with_filename) { | |
119 case 0: //default | |
120 if (argc == optind + 1) { | |
121 /* just grep 1 file. */ | |
122 env->print_filename = FALSE; | |
123 } else { | |
124 /* grep 1 more files. */ | |
125 env->print_filename = TRUE; | |
126 } | |
127 break; | |
128 // option | |
129 case -1: | |
130 env->print_filename = FALSE; | |
131 break; | |
132 case 1: | |
133 env->print_filename = TRUE; | |
134 break; | |
135 default: break; | |
136 } | |
137 for (i = optind; i < argc; i++) { | |
138 fd = open(argv[i], O_RDONLY, 0666); | |
139 if (fd == 0) { | |
140 printf("%d, %s\n", i, argv[i]); | |
141 fprintf(stderr, "can't open %s:", argv[i]); | |
142 continue; | |
143 } | |
144 env->filename = argv[i]; | |
145 grep(fd, env); | |
146 close(fd); | |
147 } | |
148 } | |
149 | |
150 return 0; | |
151 } | |
152 __code s1(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); | |
153 __code s2(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); | |
154 __code s3(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); | |
155 __code s4(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); | |
156 __code s5(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); | |
157 __code s6(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); | |
158 | |
159 void s0(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { | |
160 env->ret = (jmp_buf *)malloc(sizeof(int)*100); // allocate dumy fields. for protect real ret addres. | |
161 env->ret = (jmp_buf *)malloc(sizeof(jmp_buf)); | |
162 if (env == NULL) { | |
163 fprintf(stderr, "can't allocate jmp_buf"); | |
164 exit(0); | |
165 } | |
166 int ret; | |
167 if ((ret = setjmp(env->ret)) == 0) { | |
168 goto _s0(beg, buf, end, env); | |
169 } | |
170 //free(env->ret); danger! | |
171 return; | |
172 } | |
173 __code _s0(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { | |
174 goto filter(beg, buf, end, env); | |
175 } | |
176 | |
177 __code filter(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { | |
178 static const UCHARP const key = (UCHARP)"h"; | |
179 int i, len = 1; | |
180 loop: | |
181 while ((buf = memchr(buf, key[0], end-buf))) { | |
182 for (i = 1; i < len; i++) { | |
183 if (buf[i] != key[i]) { | |
184 buf++; | |
185 goto loop; | |
186 } | |
187 } | |
188 goto next; | |
189 } | |
190 buf = end; | |
191 goto reject(beg, buf, end, env); | |
192 next: | |
193 goto s1(beg, buf, end, env); | |
194 } | |
195 | |
196 __code s1(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { | |
197 static __code (*tbl[256])(UCHARP, UCHARP, UCHARP, ENVP) = {[0 ... 255] = (void*)s1, /* NL */ [10] = (void*)reject, /* h */ [104] = (void*)s2}; | |
198 if (buf > end) goto tbl['\n'](beg, buf, end, env); | |
199 goto tbl[*buf++](beg, buf, end, env); | |
200 } | |
201 | |
202 __code s2(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { | |
203 static __code (*tbl[256])(UCHARP, UCHARP, UCHARP, ENVP) = {[0 ... 255] = (void*)s3, /* NL */ [10] = (void*)reject, /* h */ [104] = (void*)s4}; | |
204 if (buf > end) goto tbl['\n'](beg, buf, end, env); | |
205 goto tbl[*buf++](beg, buf, end, env); | |
206 } | |
207 | |
208 __code s3(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { | |
209 static __code (*tbl[256])(UCHARP, UCHARP, UCHARP, ENVP) = {[0 ... 255] = (void*)s1, /* NL */ [10] = (void*)reject, /* c */ [99] = (void*)s5, /* h */ [104] = (void*)s2}; | |
210 if (buf > end) goto tbl['\n'](beg, buf, end, env); | |
211 goto tbl[*buf++](beg, buf, end, env); | |
212 } | |
213 | |
214 __code s4(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { | |
215 static __code (*tbl[256])(UCHARP, UCHARP, UCHARP, ENVP) = {[0 ... 255] = (void*)s3, /* NL */ [10] = (void*)reject, /* c */ [99] = (void*)s6, /* h */ [104] = (void*)s4}; | |
216 if (buf > end) goto tbl['\n'](beg, buf, end, env); | |
217 goto tbl[*buf++](beg, buf, end, env); | |
218 } | |
219 | |
220 __code s5(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { | |
221 goto accept(beg, buf - 1, end, env); | |
222 } | |
223 | |
224 __code s6(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { | |
225 goto accept(beg, buf - 1, end, env); | |
226 } | |
227 | |
228 __code | |
229 accept(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) | |
230 { | |
231 UCHARP ret = (buf < end) ? (UCHARP) memchr(buf, '\n', (end - buf)) : NULL; | |
232 if (env->print_count) { | |
233 env->count++; | |
234 if (ret == NULL) { | |
235 if (env->print_filename) { | |
236 printf("%s:", env->filename); | |
237 } | |
238 printf("%d\n", env->count); | |
239 longjmp(env->ret, 1); | |
240 } | |
241 beg = buf = ret + 1; | |
242 } else { | |
243 beg = get_line_beg(buf, beg); | |
244 if (env->print_filename) { | |
245 printf("%s:", env->filename); | |
246 } | |
247 if (ret == NULL) { | |
248 print_line(beg, end); | |
249 longjmp(env->ret, 1); | |
250 } | |
251 print_line(beg, ret); | |
252 beg = buf = ret + 1; | |
253 } | |
254 goto _s0(beg, buf, end, env); | |
255 } | |
256 | |
257 __code | |
258 reject(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { | |
259 if (buf >= end) { | |
260 if (env->print_count) { | |
261 if (env->print_filename) { | |
262 printf("%s:", env->filename); | |
263 } | |
264 printf("%d\n", env->count); | |
265 } | |
266 longjmp(env->ret, 1); | |
267 } | |
268 beg = buf; | |
269 goto _s0(beg, buf, end, env); | |
270 } |