Minix1.5/commands/fgrep.c

Compare this file to the similar file:
Show the results in this format:

/* fgrep - fast grep			Author: Jan Christiaan van Winkel */

#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>

int argc;
char **argv;
int stringlen, offset, boundary;
int i, j, k, count, linum;
char stringarea[1024];
int strptr;
int strcount;
unsigned char tbl[32][256];
int lengths[32];
char *tststring[32];
char string[512];
char tmpstring[512];
int vflag, cflag, nofname, hadone, lflag, nflag, sflag, hflag, eflag, fflag;
int fp;

main(oargc, oargv)
int oargc;
char *oargv[];

{
  int find();
  void exparg();
  void getargs();
  void gotone();

  argc = oargc;
  argv = oargv;
  getargs();

  fp = 0;
  if (i >= argc - 2 || hflag)	/* stdin, 1 file, hflag */
	nofname = 1;

  do {
	if (i < argc && (fp = open(argv[i], O_RDONLY)) < 0) {
		fprintf(stderr, "%s: can't open %s\n", argv[0], argv[i]);
		continue;
	}
	count = 0;
	linum = 0;

	while ((stringlen = getlin(fp, string, 512)) != EOF) {
		linum++;
		for (j = 0; j < strcount; j++) {
			if (find(tststring[j], tbl[j], lengths[j]) != vflag) {
				gotone();
				break;
			}
		}
		if (lflag && count) break;
	}
	close(fp);

	if (cflag) {
		printf("%s: %d times\n", argv[i], count);
	}
	if (lflag && count > 0) {
		printf("%s\n", argv[i]);
	}
  } while (++i < argc);

  fflush(stdout);
  if (hadone)
	exit(0);
  else
	exit(1);
}

void getargs()
{
  int tmp;
  void maktbl();
  for (i = 1; i < argc && argv[i][0] == '-'; i++) {
	switch (argv[i][1]) {
	    case 'e':
		eflag = 1;
		if (fflag) {
			fprintf(stderr, "%s: can't have -e and -f at the same time\n", argv[0]);
			exit(2);
		}
		if (i < argc - 1) {
			i++;
			tststring[0] = argv[i];
			strcount = 1;
		} else {
			fprintf(stderr, "%s: not enough arguments\n");
			exit(2);
		}
		break;
	    case 'v':	vflag = 1;	break;
	    case 'c':	cflag = 1;	break;
	    case 'l':	lflag = 1;	break;
	    case 's':	sflag = 1;	break;
	    case 'h':	hflag = 1;	break;
	    case 'n':	nflag = 1;	break;
	    case 'f':
		fflag = 1;
		if (eflag) {
		    fprintf(stderr, 
		       "%s: can't have -e and -f at the same time\n", argv[0]);
		    exit(2);
		}
		if (i >= argc - 1) {
			fprintf(stderr, "%s: not enough arguments\n");
			exit(2);
		} else {
			i++;
			if ((fp = open(argv[i], O_RDONLY)) < 0) {
				fprintf(stderr, 
				      "%s: can't open %s\n", argv[0], argv[i]);
				exit(2);
			}
			strcount = 0;
			while ((tmp = getlin(fp, &stringarea[strptr], 128)) != EOF) {
				tststring[strcount++] = &stringarea[strptr];
				strptr = strptr + tmp + 1;
				if (strptr >= 1024 - 128 || strcount == 32) {
					fprintf(stderr, "%s: not enough room\n", argv[0]);
					exit(2);
				}
			}
			close(fp);
		}
		break;
	    default:
		fprintf(stderr, "%s: invalid command line option\n", argv[0]);
		exit(2);
		break;
	}
	if (cflag && lflag) {
		fprintf(stderr, "%s: cannot have -l and -c at the same time\n", argv[0]);
		exit(2);
	}
  }

  if (!eflag && !fflag) {
	if (i < argc) {
		tststring[0] = argv[i++];
		strcount = 1;
	} else {
		fprintf(stderr, "%s: no search string.\n", argv[0]);
		exit(2);
	}
  }
  for (j = 0; j < strcount; j++) {
	if (tststring[j][0] == '"') {
		count = strlen(tststring[j]);
		movmem(&tststring[j][1], tststring[j], count - 2);
		tststring[j][count - 2] = '\0';
	}
	maktbl(tststring[j], tbl[j], &lengths[j]);
  }
}


movmem(src, dst, len)
char *src, *dst;
int len;
{
  while (len--) *dst++ = *src++;
}

setmem(mem, len, filler)
char *mem;
int len;
char filler;
{
  while (len--) *mem++ = filler;
}


int find(findword, table, wordlen)
unsigned char *findword;
unsigned char *table;
int wordlen;
{
  auto int lastletter, tmp;

  boundary = stringlen - wordlen;
  lastletter = wordlen - 1;
  offset = 0;
  while (offset <= boundary) {
	tmp = table[string[offset + lastletter]];
	if (tmp) {
		offset += tmp;
	} else {
		for (k = lastletter - 1; k >= 0; k--) {
			if ((string[k + offset]) != findword[k]) {
				offset++;
				break;
			}
		}
		if (k < 0) return(1);
	}
  }
  return(0);
}


void maktbl(findword, table, wordlen)
unsigned char *findword;
unsigned char *table;
int *wordlen;
{

  auto int i, len;

  *wordlen = len = strlen(findword);
  setmem(table, 256, len);
  for (i = 0; i < len; i++) table[findword[i]] = len - i - 1;
}


void gotone()
{
  hadone = 1;

  if (cflag || lflag || sflag) {
	count++;
	return;
  }
  if (!nofname) printf("%s:", argv[i]);

  if (nflag) printf("%d:", linum);

  printf("%s\n", string);
}


int getlin(infile, buf, maxlen)
int infile;
char *buf;
int maxlen;
{
  static char mybuf[2048];
  static char *low;
  static char *high;

  auto int status;
  auto char *p = buf;
  auto int endline;

  *p = '\0';
  maxlen--;
  while (1) {
	endline = 0;
	while (low < high && !endline) {
		if (p >= &buf[maxlen]) {	/* overflow, skip all
						 * until \n */
			while (low < high && *low != '\n') low++;
			endline = (*low == '\n');
		} else
			endline = ((*p++ = *low++) == '\n');

	}			/* exhausted buffer or found \n */

	/* Don't continue if \n found */
	if (endline) {
		*(p - 1) = '\0';
		return(p - buf - 1);
	}
	status = read(infile, mybuf, 2048);
	if (status <= 0) break;

	low = mybuf;
	high = &mybuf[status];

  }

  /* Empty line or a bit filled ? */
  *p = '\0';
  if (status < 0) {
	perror("read error");
	return(EOF);
  }
  if (p - buf) return(p - buf);
  return(EOF);

}				/* of getlin() */