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);
+}