Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/lo68/find.c
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

242 lines
17 KiB
C

/****************************************************************************
*
* C R U N T I M E G R E P R O U T I N E
* -------------------------------------------
* Copyright 1983 by Digital Research Inc. All rights reserved.
*
* The routine "grep" searches for an ascii character pattern in
* a series of files. "Grep" allows the following options:
*
* OPTION FUNCTION
* ------ --------
* -v Print only lines not matching the pattern
* -c Print only a count of the lines
* -n Print with line numbers
* -s Write out the sector number in which the pattern was found
* -l Write out a list of the files in which the pattern was found
* -y Do not distinguish between upper & lower case
*
* Calling Sequence:
*
* grep(options,expression,files);
*
* Where:
*
* options Is a pointer to a string of options
* expression Is a pointer to the search pattern
* files Is an array of pointers to filenames
*
*****************************************************************************/
/****************************/
/* INCLUDE FILES */
/****************************/
#include <stdio.h> /* standard I/O library */
#include <portab.h> /* CP/M portability defines */
#include <ctype.h> /* char type definitions */
/****************************/
/* GLOBAL VARIABLES */
/****************************/
GLOBAL BYTE __match = TRUE; /* Print Matching lines only*/
GLOBAL BYTE __count = FALSE; /* Just count the lines */
GLOBAL BYTE __num = FALSE; /* Print line #'s */
GLOBAL BYTE __sector = FALSE; /* Display the sector */
GLOBAL BYTE __list = FALSE; /* Display only a file list */
GLOBAL BYTE __nocase = FALSE; /* Distinguish between cases*/
GLOBAL FILE *fstream; /* file stream ptr */
GLOBAL BYTE line[129]; /* line buffer */
GLOBAL BYTE line1[129]; /* Temp line buffer */
GLOBAL BYTE first = TRUE; /* used on the list option */
GLOBAL UWORD numfound = 0; /* number of lines found */
/****************************/
/* FUNCTIONS */
/****************************/
FILE *fopenb(); /* returns a ptr to a file */
/****************************/
/* MAIN */
main(argc,argv) /* Entry point */
WORD argc; /* = # args */
BYTE **argv; /* -> args */
{ /****************************/
BYTE *options; /* Option pointer */
BYTE *expression; /* -> expression */
BYTE **files; /* -> files */
/* */
if(argc < 2) /* Must have at least 2 */
{ /* */
usage: printf("Usage: find [-options] pattern files\n");
exit(); /* */
} /****************************/
/* */
options = "-ny"; /* Set up option */
if(*argv[1] == '-') /* Options specified? */
{ /* */
options = argv[1]; /* Yes, use them */
if(argc < 3) goto usage; /* check for valid args */
expression = argv[2]; /* -> Pattern */
files = &argv[3]; /* -> file list */
} /****************************/
else { /* No options */
expression = argv[1]; /* Expression */
files = &argv[2]; /* file list */
} /****************************/
return(grep(options,expression,files)); /* Call the real function */
} /* */
/****************************/
grep(options,expression,files) /* */
REG BYTE *options; /* option list */
REG BYTE *expression; /* pattern to search for */
BYTE *files[]; /* array of files */
{ /* */
REG BYTE *p; /* temp pointer */
REG UWORD patt_cnt; /* pattern counter */
REG UWORD char_cnt; /* character count */
REG UWORD line_cnt; /* line count */
REG UWORD i; /* counter */
UWORD length; /* length of pattern */
BYTE found; /* set if pattern is found */
/* */
/* */
if(*options != '-') /* Legal option list? */
{ /* */
fprintf(stderr,"FIND--Illegal option list: %s\n",options); /* */
exit(-1); /* Just quit */
} /****************************/
while(*options) /* if found ........ */
{ /* */
switch(*++options) /* */
{ /* */
case 'v' : __match = FALSE; /* print non-matching lines */
break; /* */
case 'c' : __count = TRUE; /* print a count of lines */
break; /* */
case 'n' : __num = TRUE; /* number the lines */
break; /* */
case 's' : __sector= TRUE; /* print sector number */
break; /* */
case 'l' : __list = TRUE; /* list the files */
break; /* */
case 'y' : __nocase= TRUE; /* no case distinction */
/*break;*/ /* */
} /* */
} /* */
/****************************/
if(__list) /* list option has priority */
{ /* over these..... */
__count = FALSE; /* */
__num = FALSE; /* */
__sector = FALSE; /* */
} /* */
else /* */
if(__count) /* count option has priority*/
{ /* over these..... */
__num = FALSE; /* */
__sector = FALSE; /* */
} /* */
else /* */
if(__num) /* num option has priority */
__sector = FALSE; /* over the sector option */
if(__nocase) /* if no case destinction */
{ /* */
p = expression; /* */
while(*p) /* change expression to */
{ /* */
*p = toupper(*p); /* upper case letters */
p++; /* */
} /* */
} /* */
length = strlen(expression); /* count the characters in */
/* the pattern to match */
while(*files) /* search all the files */
{ /* */
if((fstream = fopenb(*files,"r")) != NULL)/*try to open the file */
{ /* */
char_cnt = 0; /* initialize char count */
line_cnt = 0; /* initialize line # count */
numfound = 0; /* initialize # found */
first = TRUE; /* initialize for list */
if(!__list && !__count) /* if these options are not */
{ /* ON then print the file- */
printf("\nFILE: %s\n",*files); /* name before each search */
printf("----\n"); /* */
} /* */
while(!feof(fstream)) /* go until end of file */
{ /* */
found = FALSE; patt_cnt = 0; /* */
p = expression; /* */
for(i=0;i<129;i++) /* Zap out the buffers */
line[i]=line1[i]=0; /* */
fgets(line1,129,fstream); /* read a line */
/****************************/
for(i = 0;line1[i];i++) /* */
if(__nocase) /* Translate? */
line[i] = toupper(line1[i]);/* */
else /* Don't translate */
line[i] = line1[i]; /* Just copy */
/****************************/
i = 0; /* */
while(line[i]) /* scan until a NULL */
{ /* */
char_cnt++; /* bump the char count */
if(line[i] == *p) /* check pattern */
{ /* */
p++; /* look for next char */
patt_cnt++; /* we found a character */
if(patt_cnt == length) /* Have we found the end ? */
{ /* */
found = TRUE; /* set a flag */
p = expression; /* */
patt_cnt = 0; /* */
} /* */
} /* */
else /* */
{ /* */
p = expression; /* reset the pattern ptr */
patt_cnt = 0; /* start the count over */
} /* */
i++; /* check next character */
} /* */
line[i-1] = NULL; /* mask out extra LF */
line_cnt++; /* bump the line count */
prtline(found,char_cnt,line_cnt,files);/*then print routine */
} /* */
if(__count) /* is count option ON ? */
printf("\n%s: %d",*files,numfound);/*print a count of # fnd */
} /* */
fclose(fstream); /* Close the file */
files++; /* go to next file */
} /* */
} /****************************/
/* PRINT ROUTINE */
prtline(found,char_cnt,line_cnt,files) /****************************/
BYTE found; /* does line contain pattern*/
UWORD char_cnt; /* number of chars searched */
UWORD line_cnt; /* number of lines searched */
BYTE *files[]; /* current file */
{ /****************************/
if((__match && found) || /* have we a line ? */
(!__match && !found)) /* */
{ /* */
numfound++; /* count the # lines found */
if(__count) return; /* nothing to do */
if(__list) /* if the list option */
{ /* */
if(first) /* FIRST pattern found ? */
printf("\n%s",*files); /* print the filename */
first = FALSE; /* turn off flag */
return; /* and return.. */
} /* */
if(__sector) /* do we print the sector# ?*/
{ /* */
printf("\n%d",char_cnt/128);/* divide count by 128 */
return; /* */
} /* */
if(__num) /* do we print a line # ? */
{ /* */
printf("%5d: ",line_cnt); /* */
} /* otherwise..... */
fputs(line1,stdout); /* just print the line */
} /* */
} /****************************/