[comp.sys.ibm.pc] source of simple grep for msdos and lattice-c

jchvr@ihlpg.UUCP (04/09/87)

Please find enclodes the sources for a simple version of GREP for MSDOs and LATTICE-C

when linked with PARSE.C (also included) you can say:
	grep key *.c
for example.
Regular expressions are not supported just simple keys.

Feel free to use or abuse this program at your own risk.

SOURCE PARSE.C
#include	"dos.h"
#include	"stdio.h"

/* define directory entry types */
#define	FREADONLY	0x1
#define	FHIDDEN		0x2
#define FSYSTEM		0x4
#define FLABEL		0x8
#define FDIR		0x10
#define	FARCHIVE	0x20

static union REGS rg;		/* cpu register for use of DOS calls */
static char	ar[256];

struct DTA {
	char	reserved[21];
	char	attribute;
	int	time;
	int	date;
	int	lowsize;
	int	highsize;
	char	name[13];
	char	padding;
};
static struct DTA dta;		/* copy for Disk transfer address */

static haswild(s)
char	*s;
{
	while ( *s ) {
		if ( (*s == '*') || (*s == '?') )  {
			return(1);
		}
		s++;
	}
	return(0);
}/*haswild*/

static dofile(s,f)
char	*s;
int	(*f)();
{	int i,j;
	int	res;
	
	strcpy(ar,s);

	/* set DTA */
	rg.h.ah = 0x1a;		/* set DTA */
	rg.x.dx = &(dta);
	intdos(&rg, &rg);
	
	/* start search through direc */
	rg.h.ah = 0x4e;		/* find match file */
	rg.x.cx = 0xffff;	/* all bits on */
	rg.x.dx = &(ar[0]);	/* pointer to path name */
	intdos(&rg, &rg);

	/* if nothing found then return original */
	if ( (rg.x.ax == 2) || (rg.x.ax == 18) ) {
		return((*f)(ar));
	}
	/* call func with name */
	while ( (rg.x.ax != 2) && ( rg.x.ax != 18 ) ) {
		/* do not look at labels */
		if ( (dta.attribute & FLABEL) != 0) {
			goto next;
		}
		/* do not look at dirs */
		if ( (dta.attribute & FDIR) != 0) {
			goto next;
		}
		/* else copy result and print it */		
		res = (*f)(dta.name);

next:		/* search for next entry */
		rg.h.ah = 0x4f;
		intdos(&rg, &rg);
	}
}/*dofile*/

static int	glargc;
static int	glindex;
static char	**glargv;

#define MAXARG	32
static insert(s)
char	s[];
{	int i;
	char *ptr;
	char *malloc();
	
	if (glargc >= MAXARG) {
		fprintf(stderr,"Too many arguments\n");
		exit(1);
	}
	
	/* make room for string s */
	ptr = malloc(strlen(s)+1);
	if ( ptr == NULL) {
		fprintf(stderr,"Out of memory\n");
		exit(1);
	}
	strcpy(ptr,s);
	
	/* make room at glindex by moving it all down */
	for (i=glargc; i > glindex ; i--) {
		glargv[i] = glargv[i-1];
	}
	
	/* insert s and update argc index */
	glargv[glindex] = ptr;
	glindex++;
	glargc++;
}/*insert*/

/* parse file wildcards in argv[index] while adjusting argc and index
** index is returned as index into argv where index+1 used to point
*/
_parse(argc,argv,index)
int	*argc;
char	**argv;
int	*index;
{
	char	*ptr;
	int	i;
		
	/* set global stuff */
	glargc = *argc;
	glindex= *index;
	glargv = argv;
	ptr = glargv[glindex];	/* save ptr to thing to expand */
	
	if (glindex >= glargc) {
		*index += 1;
		return;	/* no more to do */
	}
	if (haswild(ptr) == 0) {
		*index += 1;
		return;	/* nothing to do no wild */
	}
	
	/* delete item at glindex */
	glargc--;
	for (i=glindex; i<glargc; i++) {
		glargv[i]=glargv[i+1];
	}

	/* call insert routine */
	dofile(ptr,insert);
	
	/* copy global stuff */
	*argc = glargc;
	*index= glindex;
}/*_parse*/

/* parse all argv[i] starting at i=index */
_parseall(argc,argv,index)
int	*argc;
char	**argv;
int	index;
{	int i;
	while ( index < *argc ) {
		_parse(argc,argv,&index);
	}
}/*_parseall*/

SOURCE grep.c
/* search.c -*-update-version-*-
** HFVR VERSION=Wed Jan  7 08:03:10 1987
*/
#include <stdio.h>
#include <ctype.h>

#define MIN(a,b)	( (a) < (b) ? (a) : (b) )
#define	TSIZE		128
#define void	int

char	*tobesearched;

void initfsindex(s,t)
register char	*s;
register int	t[];
{ 
	register int i;
	register int slength;
	register int *p;

	slength = strlen(s);
	for ( i = 0 ; i < TSIZE ; i++ ) t[i] = slength;

	for ( i = 0 ; i < slength ; i++ ) {
		p = &t[s[i]];
		*p = MIN( *p, slength-1-i );
	}
}/*initfsindex*/

/* fsindex: return pointer to where small starts in big, or NULL if
** not found. pos must be initialized by call to initfsindex */
char *fsindex(big,small,pos)
char	*big;
char	*small;
int	pos[];
{ 
	register char *pb;
	register char *ps;
	register char *lpb;	/* start value for pb */
	register char *pes;
	register char *peb;
	int slength;

	/* ABCD.     DEFGH.	where . means EOS
	** 01234     012345
	**  ^ ^       ^   ^
	**  | |       |   |
	** ps pes     pb  peb
	*/

	slength = strlen(small);
	if ( slength == 0 ) return(big);
	pes = &small[slength-1];	/* points to last char of small */
	peb = &big[strlen(big)];	/* points to EOS in big */
	lpb = &big[slength-1];		/* starting point for search */

l1:
	if ( lpb < peb ) {	/* then not past end of big */
		pb = lpb;	/* set start for big */
		ps = pes;	/* set to end of small */

l2:
		if ( *pb != *ps ) {	/* then not found so skip */
			lpb++;		/* skip one char */
			lpb += ( *lpb < (char)TSIZE ? pos[*lpb] : slength );
			goto l1;
		}
		if ( ps != small) {	/* then not full small found yet */
			ps--;
			pb--;
			goto l2;	/* try previous char in small */
		} else {
			return(pb);	/* full small found at pb */
		}
	} else {
		return(NULL);	/* not found */
	}
}/*fsindex*/

/* sindex: returns pointer to start of small in big, or NULL if not found
** calls fsindex after initializing */
char *sindex(big,small)
char big[];
char small[];
{ 
	int	table[TSIZE];
	initfsindex(small,table);
	return(fsindex(big,small,table));
}/*sindex*/

int table[TSIZE];
FILE *fp;
char *filename;
char noname[] = "";

#define LENGTH 2048
char line[LENGTH];

int workon(s)
char	s[];
{ register char *lp;
  register int res;
  
  res = 1;
  while (  (lp = fgets(line,LENGTH,fp)) != NULL ) {
    if ( fsindex(line,s,table) != NULL ) {
     res = 0;
     if ( filename != noname ) printf("%s:",filename);
     printf("%s",line);
    }
  }
  return(res);
}/*workon*/

int main(argc,argv)
int	argc;
char	*argv[];
{ register int res;	/* result */
  int i;
  
#ifdef MSDOS
   _parseall(&argc,argv,2);
#endif

  tobesearched = argv[1];
  res = 1;
  filename = noname;
  if ( argc <= 1 ) {
    fprintf(stderr,"\007Usage: %s <string> <files>*\n",argv[0]);
    exit(1);
  }

/* set search table */
  initfsindex(tobesearched,table);

/* work on stdin if no files given */
  if ( argc == 2 ) {
   fp = stdin;
   exit(workon(tobesearched));
  }

  for(i=2; i<argc; i++) {
   fp = fopen(argv[i],"r");
   if (NULL == fp ) {
	fprintf(stderr,"grep : ERROR : cannot open %s\n",argv[i]);
   } else {
     	if (argc > 3) filename = argv[i];
     	res = workon(tobesearched);
     	fclose(fp);
   }/*fi*/
 }/*for*/
   exit(res);
}/*main*/

Good luck.