view src/template/grep.c @ 24:ceb0b8a73d68

add grep.c, it was introduced by Brian W. Kernighan and Rob Pike in "The Practice of Programming"
author Ryoma SHINYA <shinya@firefly.cr.ie.u-ryukyu.ac.jp>
date Tue, 06 Jul 2010 05:39:41 +0900
parents
children 3db85244784b
line wrap: on
line source

/* Excerpted from 'The Practice of Programming' */
/* by Brian W. Kernighan and Rob Pike */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFSIZE 1024

int match(char *regexp, char *text) {
  if (regexp[0] == '^')
    return matchhere(regexp+1, text);
  do {
    if (matchhere(regexp+1, text))
      return 1;
  } while (*text++ != '\0');
  return 0;
}

int matchhere(char *regexp, char *text) {
  if (regexp[0] == '\0')
    return 1;
  if (regexp[1] == '*')
    return matchstar(regexp[0], regexp+2, text);
  if (regexp[0] == '$' && regexp[1] == '\0')
    return *text == '\0';
  if (*text != '\0' && (regexp[0] == '.' || regexp[0] == *text))
    return matchhere(regexp+1, text+1);
  return 0;
}

int matchstar(int c, char *regexp, char *text) {
  do {
    if (matchhere(regexp, text))
      return 1;
  } while (*text != '\0' && (*text++ == c || c == '.'));
  return 0;
}

int grep(char * regexp, FILE *f, char *name) {
  int n, nmatch;
  char buf[BUFSIZE];
  nmatch = 0;
  while (fgets(buf, sizeof buf, f) != NULL) {
    n = strlen(buf);
    if (n > 0 && buf[n-1] == '\n')
      buf[n-1] = '\0';
    if (match(regexp, buf)) {
      nmatch++;
      if (name != NULL)
        printf("%s:", name);
      printf("%s\n", buf);
    }
  }
  return nmatch;
}

int main(int argc, char* argv[]) {
  int i, nmatch;
  FILE *f;

  if (argc < 2) {
    fprintf(stderr, "usage: grep regexp [file ...]");
    exit(0);
  }
  nmatch = 0;
  if (argc == 2) {
    if (grep(argv[1], stdin, NULL))
      nmatch;
  } else {
    for (i = 2; i < argc; i++) {
      f = fopen(argv[i], "r");
      if (f == NULL) {
        fprintf(stderr, "can't open %s:", argv[i]);
        continue;
      }
      if (grep(argv[1], f, argc > 3 ? argv[i] : NULL) > 0)
        nmatch++;
      fclose(f);
    }
  }

  return nmatch;
}