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 }