view pyrect/pyrect/grep.c @ 9:493c96d030c0

add pyrect
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 14 Jun 2011 17:24:03 +0900
parents
children 41634f26cd6f
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 <pthread.h>

typedef unsigned char   UCHAR;
typedef unsigned char *UCHARP;
typedef struct env_ {
  void (*ret)();
  int count;
} ENV;
typedef ENV *ENVP;

typedef struct THARG {
  int *fdp;
  UCHARP beg, buf, end;
} THARG;
typedef THARG *THARGP;

int matcher(UCHARP beg, UCHARP buf, UCHARP end);
void *matcherp(void *p);

__code entry(UCHARP beg, UCHARP buf, UCHARP end, ENVP envp);

__code accept(UCHARP beg, UCHARP buf, UCHARP end, ENVP envp);
__code reject(UCHARP beg, UCHARP buf, UCHARP end, ENVP envp);

UCHARP get_line_beg(UCHARP p, UCHARP beg);
void createArg(THARGP p, int *fdp, UCHARP beg, UCHARP buf, UCHARP end); 
void mallocTh(pthread_t *threads, int num);
void createArgs(THARGP *p, int *fdp, UCHARP beg, UCHARP buf, off_t size, int num);

__code quick_filter(UCHARP beg, UCHARP buf, UCHARP end, ENVP envp) {
  static const UCHAR key[] = "ABC";
  UCHARP tmp1, tmp2, end_ = end - 2;

  while (buf < end_) {
    if (*buf == 65 /* 'A' */) {
      tmp1 = buf, tmp2 = (UCHARP)key;
      while (*(++tmp1) == *(++tmp2)){
        if (tmp2 == key+2) goto next;
      }
    }
    switch(buf[3]) {
      case 65: /* 'A' */
        buf += 3; break;
      case 67: /* 'C' */
        buf += 1; break;
      case 66: /* 'B' */
        buf += 2; break;
      default: buf += 4;
    }
  }
  (*envp->ret)();
  next:
  goto accept(beg, buf, end, envp);
}

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(char *regexp, int fd, char *name) {
  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", name);
    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", name);
    exit(0);
  }

  beg = buf = (UCHARP) file_mmap;
  end = beg + size - 1;
  
  int iret;
  THARG tharg;
  
  int num = 2;
  THARGP *thargs = malloc(sizeof(THARG) * num);
  createArgs( thargs, &fd, beg, buf, size, num);


  pthread_t *threads  = malloc(sizeof(pthread_t) * num);
  mallocTh( threads, num);

  //  createArg( &tharg, &fd, beg, buf, end);
  //  iret = pthread_create( &threads[0], NULL, matcherp, (void*)&tharg );

  int i;
  for (i=0; i<num; i++){
    iret = pthread_create( &threads[i], NULL, matcherp, (void*)thargs[0] );
  }  
  //  matcher(beg, beg, end);

  for ( i=0; i<num; i++) {
    pthread_join( threads[i], NULL);
  }
  munmap(file_mmap, size);
  return;
}

int main(int argc, char* argv[]) {
  int i, fd;

  if (argc < 2) {
    fprintf(stderr, "usage: grep regexp [file ...]");
    exit(0);
  }
  if (argc == 2) {
    return 0;
  } else {
    for (i = 2; i < argc; i++) {
      fd = open(argv[i], O_RDONLY, 0666);
      if (fd == 0) {
        fprintf(stderr, "can't open %s:", argv[i]);
        continue;
      }
      grep(argv[1], fd, argc > 3 ? argv[i] : NULL);
      close(fd);
    }
  }

  return 0;
}

int matcher(UCHARP beg, UCHARP buf, UCHARP end) {
  __label__ _return;
  void __return() {
    goto _return;
  }
  ENV env;
  env.ret = __return;
  env.count = 0;
  goto entry(beg, buf, end, &env);
_return:
  return env.count;
}

void *matcherp(void *p) {
  __label__ _end;
  void __end() {
    goto _end;
  }
  ENV env;
  env.ret = __end;
  env.count = 0;
  THARGP tharg = (THARGP)p;
  goto entry(tharg->beg, tharg->buf, tharg->end, &env);
_end:
  exit(0);
}

__code entry(UCHARP beg, UCHARP buf, UCHARP end, ENVP envp) {
  goto quick_filter(beg, buf, end, envp);
}

__code accept(UCHARP beg, UCHARP buf, UCHARP end, ENVP envp) {
  UCHARP ret = (UCHARP)memchr(buf, '\n', (buf - end));
  beg = get_line_beg(buf, beg);
  if (ret == NULL) {
    print_line(beg, end);
    (*envp->ret)();
  }
  print_line(beg, ret);
  beg = buf = ret + 1;
  goto entry(beg, buf, end, envp);
}

__code reject(UCHARP beg, UCHARP buf, UCHARP end, ENVP envp) {
  if (buf >= end) (*envp->ret)();
  beg = buf;
  goto entry(beg, buf, end, envp);
}

void createArg(THARGP p, int *fdp, UCHARP beg, UCHARP buf, UCHARP end ) {
  p->fdp = fdp;
  p->beg = beg;
  p->buf = buf;
  p->end = end;
}

void createArgs(THARGP *p, int *fdp, UCHARP beg, UCHARP buf, off_t size, int num) {
  int i;
  
  off_t dsize = size / num;
  off_t rem = size % num;
  UCHARP end;
  for ( i=1; i<num+1; i++) {
    p[1-i] = malloc(sizeof(THARG));
    end = beg + dsize * i;
    createArg( p[1-i], fdp, beg+dsize*(i-1), buf+dsize*(i-1), end);
  }
}


void mallocTh(pthread_t *threads, int num) {
  int i;
  threads = malloc(sizeof(pthread_t) * num);

  for( i=0; i<num; i++) {
    threads[i] = malloc(sizeof(pthread_t));
  }
}