"egrep" is too slow and has lousy error checking

Guy Harris guy at sun.uucp
Fri May 16 08:15:29 AEST 1986


1) "egrep" tests whether the "-i" flag was set on every character.  It
doesn't have to do this; it could test it when it builds the goto function
and modify the goto function if set.

2) "egrep" thinks an I/O error is equivalent to an EOF, and has various
other problems similar to the ones mentioned in an earlier posting on
"fgrep".

Here's a context diff of the fixes:

*** egrep.slow.y	Thu May 15 15:06:27 1986
--- egrep.fast.y	Thu May 15 15:06:09 1986
***************
*** 42,47 ****
--- 42,49 ----
  int icount;
  char *input;
  
+ void exit();
+ 
  long	lnum;
  int	bflag;
  int	cflag;
***************
*** 61,66 ****
--- 63,69 ----
  int	nsucc;
  
  int	f;
+ char	*fname;
  %}
  
  %%
***************
*** 166,172 ****
  nextch() {
  	register int c;
  	if (fflag) {
! 		if ((c = getc(expfile)) == EOF) return(0);
  	}
  	else c = *input++;
  	return(c);
--- 169,183 ----
  nextch() {
  	register int c;
  	if (fflag) {
! 		if ((c = getc(expfile)) == EOF) {
! 			if (ferror(expfile)) {
! 				fprintf(stderr, "egrep: Read error on ");
! 				perror(fname);
! 				exit(1);
! 			}
! 			fclose(expfile);
! 			return(0);
! 		}
  	}
  	else c = *input++;
  	return(c);
***************
*** 320,325 ****
--- 331,342 ----
  				}
  			}
  		}
+ 		if (iflag) {
+ 			for (c=0; c<NCHARS; c++) {
+ 				if (isupper(c))
+ 					gotofn[s][c] = gotofn[s][tolower(c)];
+ 			}
+ 		}
  	}
  }
  
***************
*** 446,457 ****
  			continue;
  
  		case 'f':
! 			fflag++;
! 			expfile = fopen(optarg,"r");
! 			if (expfile == NULL) {
! 				fprintf(stderr, "egrep: can't open %s\n", optarg);
  				exit(2);
  			}
  			continue;
  
  		case 'l':
--- 463,474 ----
  			continue;
  
  		case 'f':
! 			if (fflag) {
! 				fprintf(stderr, "egrep: Only one \"-f\" option allowed\n");
  				exit(2);
  			}
+ 			fflag++;
+ 			fname = optarg;
  			continue;
  
  		case 'l':
***************
*** 471,501 ****
  	}
  
  	argc -= optind;
! 	if (errflg || ((argc <= 0) && !fflag)) {
  		printf("usage: egrep %s\n",usage);
  		exit(2);
  	}
- 	if ( !eflag  && !fflag ) {
- 		input = argv[optind];
- 		optind++;
- 		argc--;
- 	}
  
! 	if (iflag) {
! 		for (arg = input; *arg != NULL; ++arg)
! 			*arg = (char)tolower((int)(*arg));
! 	}
! 
! 	argv = &argv[optind];
! 	if(argc > 0)
! 		if (access(*argv, 0) != 0) {
! 			fprintf(stderr, "egrep: %s does not exist\n", *argv);
  			exit(2);
  		}
  	yyparse();
  
  	cfoll(line-1);
  	cgotofn();
  	nfile = argc;
  	if (argc<=0) {
  		if (lflag) exit(1);
--- 488,527 ----
  	}
  
  	argc -= optind;
! 	if (errflg || ((argc <= 0) && !fflag && !eflag)) {
  		printf("usage: egrep %s\n",usage);
  		exit(2);
  	}
  
! 	if (fflag) {
! 		expfile = fopen(fname, "r");
! 		if (expfile == (FILE *)0) {
! 			fprintf(stderr, "egrep: ");
! 			perror(fname);
  			exit(2);
  		}
+ 	} else {
+ 		if (!eflag) {
+ 			input = argv[optind];
+ 			optind++;
+ 			argc--;
+ 		}
+ 		if (iflag) {
+ 			arg = input;
+ 			while ((c = *arg) != '\0') {
+ 				if (isupper(c))
+ 					*arg++ = tolower(c);
+ 				else
+ 					arg++;
+ 			}
+ 		}
+ 	}
+ 
  	yyparse();
  
  	cfoll(line-1);
  	cgotofn();
+ 	argv = &argv[optind];
  	nfile = argc;
  	if (argc<=0) {
  		if (lflag) exit(1);
***************
*** 521,527 ****
  	int in_line;
  	if (file) {
  		if ((fptr = fopen(file, "r")) == NULL) {
! 			fprintf(stderr, "egrep: can't open %s\n", file);
  			nsucc = 2;
  			return;
  		}
--- 547,554 ----
  	int in_line;
  	if (file) {
  		if ((fptr = fopen(file, "r")) == NULL) {
! 			fprintf(stderr, "egrep: ");
! 			perror(file);
  			nsucc = 2;
  			return;
  		}
***************
*** 535,549 ****
  	blkno = 0;
  	p = buf;
  	nlp = p;
! 	if ((ccount = fread(p, sizeof(char), BUFSIZ, fptr)) <= 0) goto done;
  	in_line = 1;
  	istat = cstat = gotofn[0]['\n'];
  	if (out[cstat]) goto found;
  	for (;;) {
! 		if (!iflag)
! 			cstat = gotofn[cstat][*p&0377];	/* all input chars made positive */
! 		else
! 			cstat = gotofn[cstat][tolower((int)*p&0377)]; /* for -i option*/
  		if (out[cstat]) {
  		found:	for(;;) {
  				if (*p++ == '\n') {
--- 562,577 ----
  	blkno = 0;
  	p = buf;
  	nlp = p;
! 
! 	if ((ccount = fread(p, sizeof(char), BUFSIZ, fptr)) < 0)
! 		goto readerr;
! 	else if (ccount == 0)
! 		goto done;
  	in_line = 1;
  	istat = cstat = gotofn[0]['\n'];
  	if (out[cstat]) goto found;
  	for (;;) {
! 		cstat = gotofn[cstat][*p&0377];	/* all input chars made positive */
  		if (out[cstat]) {
  		found:	for(;;) {
  				if (*p++ == '\n') {
***************
*** 584,589 ****
--- 612,619 ----
  						ccount = fread(p, sizeof(char), &buf[2*BUFSIZ] - p, fptr);
  					}
  					if (ccount <= 0) {
+ 						if (ccount < 0)
+ 							goto readerr;
  						if (in_line && (vflag == 0)) {
  							in_line = 0;
  							goto succeed;
***************
*** 617,622 ****
--- 647,654 ----
  				ccount = fread(p, sizeof(char), &buf[2*BUFSIZ] - p, fptr);
  			}
  			if (ccount <= 0) {
+ 				if (ccount < 0)
+ 					goto readerr;
  				if (in_line && vflag) {
  					in_line = 0;
  					goto succeed;
***************
*** 633,636 ****
--- 665,675 ----
  			printf("%s:", file);
  		printf("%ld\n", tln);
  	}
+ 	return;
+ 
+ readerr:
+ 	fprintf(stderr, "egrep: Read error on ");
+ 	perror(file ? file : "standard input");
+ 	nsucc = 2;
+ 	fclose(fptr);
  }
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy at sun.arpa



More information about the Net.bugs.usg mailing list