Mercurial > hg > Game > Cerium
view example/regex/ppe/grep.c @ 1467:d585a7614cd5 draft
look like working now.
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 15 Jul 2012 17:33:50 +0900 |
parents | 2abd68a1ac2a |
children |
line wrap: on
line source
#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> 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; bool print_count; bool print_filename; int count; char *filename; } *ENVP; void filter(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); void predict(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); void reject(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); void accept(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); void s0(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); #define __REGEX__ "h.s" 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 = (char*)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; } void s1(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); void s2(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); void s3(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); void s4(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); void s5(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); void s6(UCHARP beg, UCHARP buf, UCHARP end, ENVP env); void s0(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { return filter(beg, buf, end, env); } void filter(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { static const UCHARP key = (UCHARP)"h"; int i, len = 1; loop: while ((buf = (UCHARP)memchr(buf, key[0], end-buf))) { for(i = 1; i < len; i++) { if (buf[i] != key[i]) { buf++; goto loop; } } goto next; } return reject(beg, end, end, env); next: return s1(beg, buf, end, env); } void s1(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { static void (*tbl[256])(UCHARP, UCHARP, UCHARP, ENVP) = {[0 ... 255] = (void*)s1, /* NL */ [10] = (void*)reject, /* h */ [104] = (void*)s2 }; if (buf > end) return tbl['\n'](beg, buf, end, env); return tbl[*buf++](beg, buf, end, env); } void s2(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { static void (*tbl[256])(UCHARP, UCHARP, UCHARP, ENVP) = {[0 ... 255] = (void*)s3, /* NL */ [10] = (void*)reject, /* h */ [104] = (void*)s4}; if (buf > end) return tbl['\n'](beg, buf, end, env); return tbl[*buf++](beg, buf, end, env); } void s3(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { static void (*tbl[256])(UCHARP, UCHARP, UCHARP, ENVP) = {[0 ... 255] = (void*)s1, /* NL */ [10] = (void*)reject, /* h */ [104] = (void*)s2, /* s */ [115] = (void*)s5}; if (buf > end) return tbl['\n'](beg, buf, end, env); return tbl[*buf++](beg, buf, end, env); } void s4(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { static void (*tbl[256])(UCHARP, UCHARP, UCHARP, ENVP) = {[0 ... 255] = (void*)s3, /* NL */ [10] = (void*)reject, /* h */ [104] = (void*)s4, /* s */ [115] = (void*)s6}; if (buf > end) return tbl['\n'](beg, buf, end, env); return tbl[*buf++](beg, buf, end, env); } void s5(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { return accept(beg, buf - 1, end, env);} void s6(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { return accept(beg, buf - 1, end, env);} void accept(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { if (buf < beg) buf = beg; 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); return; } 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); return; } print_line(beg, ret); beg = buf = ret + 1; } return s0(beg, buf, end, env); } void reject(UCHARP beg, UCHARP buf, UCHARP end, ENVP env) { UCHARP ret; if (buf >= end) { ret = NULL; } else { if (*(buf-1) == '\n') { ret = buf-1; } else { ret = (UCHARP)memchr(buf, '\n', (end - buf)); } } if (ret == NULL) { if (env->print_count) { if (env->print_filename) { printf("%s:", env->filename); } printf("%d\n", env->count); } return; } beg = buf = ret + 1; return s0(beg, buf, end, env); }