Mercurial > hg > Members > nobuyasu > test
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/regen/src/grep/grep_jobs.cbc.c~ Tue Jun 28 16:25:37 2011 +0900 @@ -0,0 +1,270 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <setjmp.h> + +typedef unsigned char UCHAR; +typedef unsigned char* UCHARP; + +typedef enum BOOL { + FALSE = 0, + TRUE = 1 +} BOOL; + +typedef struct ENV { + BOOL print_count; + BOOL print_filename; + int count; + char *filename; + jmp_buf *ret; +} *ENVP; + +__code filter(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); +__code predict(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); +__code reject(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); +__code accept(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); +void s0(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); +__code _s0(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); +#define __REGEX__ "h.c" + +UCHARP get_line_beg(UCHARP p, UCHARP beg) { + while(p > beg) { + if ((*--p) == '\n') return p+1; + } + return beg; +} + +void print_line(UCHARP beg, UCHARP end) { + fwrite(beg, sizeof(char), (end - beg + 1), stdout); +} + +void grep(int fd, ENVP env) { + caddr_t file_mmap; + UCHARP buf, end, beg; + off_t size; + struct stat sb; + + if (fstat(fd, &sb)) { + fprintf(stderr, "can't fstat %s\n", env->filename); + exit(0); + } + + size = sb.st_size; + file_mmap = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, (off_t)0); + + if (file_mmap == (caddr_t)-1) { + fprintf(stderr, "can't mmap %s\n", env->filename); + exit(0); + } + + beg = buf = (UCHARP) file_mmap; + end = beg + size - 1; + env->count = 0; + + s0(beg, beg, end, env); + + munmap(file_mmap, size); + return; +} + +void stdingrep(ENVP env) { + char buf_[BUFSIZ]; + UCHARP buf, beg, end; + buf = beg = (UCHARP) buf_; + + while (fgets(buf_, BUFSIZ, stdin) != NULL) { + env->count = 0; + end = buf + strlen(buf_) - 1; + s0(beg, buf, end, env); + } +} + +int main(int argc, char* argv[]) { + int i, fd, opt, with_filename = 0; + + ENVP env = (ENVP)calloc(sizeof(ENVP), 1); + + while ((opt=getopt(argc, argv, "chH")) != -1) { + switch (opt) { + case 'c': + env->print_count = 1; + break; + case 'h': + with_filename = -1; + break; + case 'H': + with_filename = 1; + break; + default: + fprintf(stderr, "invalid option."); + exit(0); + } + } + + if (optind == argc) { + if (with_filename) { + /* handle -h/-H as help */ + printf("grep pattern: %s\n", __REGEX__); + exit(1); + } else { + stdingrep(env); + } + } else { + switch (with_filename) { + case 0: //default + if (argc == optind + 1) { + /* just grep 1 file. */ + env->print_filename = FALSE; + } else { + /* grep 1 more files. */ + env->print_filename = TRUE; + } + break; + // option + case -1: + env->print_filename = FALSE; + break; + case 1: + env->print_filename = TRUE; + break; + default: break; + } + for (i = optind; i < argc; i++) { + fd = open(argv[i], O_RDONLY, 0666); + if (fd == 0) { + printf("%d, %s\n", i, argv[i]); + fprintf(stderr, "can't open %s:", argv[i]); + continue; + } + env->filename = argv[i]; + grep(fd, env); + close(fd); + } + } + + return 0; +} +__code s1(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); +__code s2(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); +__code s3(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); +__code s4(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); +__code s5(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); +__code s6(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); + +void s0(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { + env->ret = (jmp_buf *)malloc(sizeof(int)*100); // allocate dumy fields. for protect real ret addres. + env->ret = (jmp_buf *)malloc(sizeof(jmp_buf)); + if (env == NULL) { + fprintf(stderr, "can't allocate jmp_buf"); + exit(0); + } + int ret; + if ((ret = setjmp(env->ret)) == 0) { + goto _s0(beg, buf, end, env); + } + //free(env->ret); danger! + return; +} +__code _s0(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { + goto filter(beg, buf, end, env); +} + +__code filter(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { + static const UCHARP const key = (UCHARP)"h"; + int i, len = 1; +loop: + while ((buf = memchr(buf, key[0], end-buf))) { + for (i = 1; i < len; i++) { + if (buf[i] != key[i]) { + buf++; + goto loop; + } + } + goto next; + } + buf = end; + goto reject(beg, buf, end, env); +next: + goto s1(beg, buf, end, env); +} + +__code s1(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { + static __code (*tbl[256])(UCHARP, UCHARP, UCHARP, ENVP) = {[0 ... 255] = (void*)s1, /* NL */ [10] = (void*)reject, /* h */ [104] = (void*)s2}; + if (buf > end) goto tbl['\n'](beg, buf, end, env); + goto tbl[*buf++](beg, buf, end, env); +} + +__code s2(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { + static __code (*tbl[256])(UCHARP, UCHARP, UCHARP, ENVP) = {[0 ... 255] = (void*)s3, /* NL */ [10] = (void*)reject, /* h */ [104] = (void*)s4}; + if (buf > end) goto tbl['\n'](beg, buf, end, env); + goto tbl[*buf++](beg, buf, end, env); +} + +__code s3(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { + static __code (*tbl[256])(UCHARP, UCHARP, UCHARP, ENVP) = {[0 ... 255] = (void*)s1, /* NL */ [10] = (void*)reject, /* c */ [99] = (void*)s5, /* h */ [104] = (void*)s2}; + if (buf > end) goto tbl['\n'](beg, buf, end, env); + goto tbl[*buf++](beg, buf, end, env); +} + +__code s4(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { + static __code (*tbl[256])(UCHARP, UCHARP, UCHARP, ENVP) = {[0 ... 255] = (void*)s3, /* NL */ [10] = (void*)reject, /* c */ [99] = (void*)s6, /* h */ [104] = (void*)s4}; + if (buf > end) goto tbl['\n'](beg, buf, end, env); + goto tbl[*buf++](beg, buf, end, env); +} + +__code s5(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { + goto accept(beg, buf - 1, end, env); +} + +__code s6(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { + goto accept(beg, buf - 1, end, env); +} + +__code +accept(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) +{ + UCHARP ret = (buf < end) ? (UCHARP) memchr(buf, '\n', (end - buf)) : NULL; + if (env->print_count) { + env->count++; + if (ret == NULL) { + if (env->print_filename) { + printf("%s:", env->filename); + } + printf("%d\n", env->count); + longjmp(env->ret, 1); + } + beg = buf = ret + 1; + } else { + beg = get_line_beg(buf, beg); + if (env->print_filename) { + printf("%s:", env->filename); + } + if (ret == NULL) { + print_line(beg, end); + longjmp(env->ret, 1); + } + print_line(beg, ret); + beg = buf = ret + 1; + } + goto _s0(beg, buf, end, env); +} + +__code +reject(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { + if (buf >= end) { + if (env->print_count) { + if (env->print_filename) { + printf("%s:", env->filename); + } + printf("%d\n", env->count); + } + longjmp(env->ret, 1); + } + beg = buf; + goto _s0(beg, buf, end, env); +}