/* Fast find for searching large source for a string - John N. White */
/* The first arg is the string, any additional args must be on the same line
 * (of the source file) in the correct order for the line to be printed.
 * The names of files to be searched are read from stdin untill EOF */
#define stdin 0		/* DeSmet value for stdin */
int f,curflag,fs,fe;
char *fname,fbuf[2048],line[258],curfile[128];
char *le,*lend= &line[256];

main(argc,argv)
char **argv;{
	int i,j;
	if(argc<2){
		puts("need string to search for");
		exit(1);
	}
	findall(argc,argv);
}

/* find next file and set f to it */
nextfile(){
	int c,i;
	if(f>0) close(f);
	curflag=1;
	fe=fs=2048;
loop:
	while((c=getc(stdin))<=' ' || c==',') if(c<0) exit(0);
	i=0;
	do{ if(i<127) curfile[i++]=c; }
		while((c=getc(stdin))>' ' && c!=',');
	curfile[i]=0;
	f=open(curfile,0);
	if(f<=0){
		puts("******** can't open file ");
		puts(curfile);
		puts("\n");
		goto loop;
	}
}

/* find all lines in the current file containing string */
findall(argc,argv)
char **argv;{
	char *p,*q,*r,*string;
	int c;
	string=argv[1];
	c= *string;
loop:
	getline();
	for(p=line;p<le;p++) if(*p==c){
		for(q=p,r=string;*r && *r== *q;q++,r++);
		if(!*r && cmpnext(argc,argv,q)){
			if(curflag){
				puts("---- file: ");
				puts(curfile);
				puts(" ----\n");
				curflag=0;
			}
			puts(line);
			puts("\n");
			goto loop;
		}
	}
	goto loop;
}

/* compare next arg with remainder of string, ret true if ok */
cmpnext(argc,argv,cline)
char **argv, *cline;{
	char *p,*q,*r,*string;
	int c;
	if(argc<3) return(1);	/* if no more args */
	string=argv[2];
	c= *string;
	for(p=cline;p<le;p++) if(*p==c){
		for(q=p,r=string;*r && *r== *q;q++,r++);
		if(!*r && cmpnext(argc-1,argv+1,q)) return(1);
	}
	return(0);
}

/* get the next line of the current file into line */
getline(){
	int j;
loop:
	if(fe<1) nextfile();
	for(le=line;
		(j=fs<fe?fbuf[fs++]:((fs=1,(fe=read(f,fbuf,2048))<1)?'\n':*fbuf))!='\n'
		&& le<lend;
		le++) *le=j;
	*le=0;
	if(! *line) goto loop;
}
