view regen/src/grep/grep_jobs.cbc.c~ @ 15:b48915bffa79 draft default tip

commit search.py
author Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
date Sun, 01 Jul 2012 00:31:22 +0900
parents a6f51c76dea8
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>
#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);
}