#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Program to read text from a file or from stdin, buffering text and searching for a string.
When 2 CRs are found (a paragraph) if a match was found in it the buffer is
printed to stdout. The buffer is cleared and reading contuned.
The effect is to print the entire paragraph if it contains a match.
*/
FILE *intext;
typedef char bufstr[0x7fff]; //32k buffer
typedef char shortstr[63];
typedef char filenamestr[255];
bufstr buffer;
int bufpos;
shortstr srchst, SRCHST;
char Ch, LastCh;
char t;
filenamestr filename;
int Found, ReadFromStdIn, i, BufOverflow;
int SrchIndex;
int ShowFn; /*If ShowFn then display Fn before displaying lines */
void AddCh (char c) {
if (bufpos < sizeof(buffer)-2) {
buffer[bufpos] = c;
bufpos ++;
buffer[bufpos] = 0;
}
else {
BufOverflow = 1;
printf ("buffer full, program terminated\n");
}
}
void ClearBuf () {
bufpos = 0;
buffer[bufpos] = 0;
}
void PrintBuf () {
printf("%s", buffer);
printf("\n");
}
void stupper(char *str) { /* string uppercase, usage: stupper(srchst); */
int i; /*this uppercases the original */
for (i = 0; str[i]; i++)
str[ i ] = toupper( str[ i ] );
}
void stlower(char *str) { /* string lowercase, usage: stlower(srchst); */
int i; /*this lowercases the original */
for (i = 0; str[i]; i++)
str[ i ] = tolower( str[ i ] );
}
void syntax(char *prog) { /* this does work (call syntax(srchst) */
printf("Syntax: cat filename | %s [-f] [-h] srchst\n", prog);
printf(" filename is piped into %s. Paragraphs that contain srchst\n", prog);
printf(" are printed. srch is not case sensitive.\n");
printf(" Use double quotes around multi-word srearch phrases.\n");
printf("Or,");
printf("Syntax: %s srchst filename\n", prog);
printf(" -h Help\n");
printf(" -f Display filename of files that contain srchst\n");
}
/* ********************************************************* */
int main ( int argc, char *argv[] ) {
int i, stlen;
BufOverflow = 0;
ShowFn = 0; /* Set this to 1 if filename is to be displayed, 0 otherwise */
// FnContains = 0;
ReadFromStdIn = 1;
filenamestr argument;
int args, ArgNum;
ArgNum = 0;
args=argc;
if (argc == 1) { /*Should be > 1; argc[1] = argv[0] is programname */
strncpy(filename, argv[0], sizeof(filename)-1); //copy programname to srchst for syntax to use
syntax(filename);
return 1; //Exit with error 1
}
for (i = 1; i < args; i++) {
strncpy(argument, argv[i], sizeof(argument)-1);
if (argument[0] == '-') {
/* printf("we have a hyphen\n"); */
switch (argument[1]) {
case 'h': strncpy(filename, argv[0], sizeof(filename)-1);
syntax(filename);
return 1;
break;
case 'f': ShowFn = 1;
break;
default: printf("Unrecognized switch %c\n", argument[1]);
break;
} //switch
} //if
else {
ArgNum ++;
switch (ArgNum) {
case 1: strncpy(srchst, argument, sizeof(srchst)-1); break;
case 2: strncpy(filename, argument, sizeof(filename)-1);
ReadFromStdIn = 0; break;
default: printf("Too many Arguments\n"); break;
} //switch
} //else
} // for
strcpy(SRCHST, srchst);
stupper(SRCHST); //The uppercase search string
stlower(srchst); //The lowercase one
if (ReadFromStdIn == 0) {
intext=fopen(filename,"r"); /* open filename for reading */
}
else {
intext=fopen("/dev/stdin","r"); /* open stdin for reading */
}
/* printf("reading in file...\n");*/
if(intext == NULL) /* did it open? */
printf ("unable to open file");
else { //OK, let's do it
Found = 0;
LastCh = 0;
Ch = 0;
Found = 0;
SrchIndex=0;
do {
if (Ch != ' ') /*Do not count a line of spaces as a line of text*/
LastCh = Ch;
Ch = fgetc(intext);
if( feof(intext) )
break ;
if (Ch == '\n' && LastCh == '\n') { //if 2 CRs in a row
/* printf("New Paragraph\n"); */
if (Found == 1) //If anything found the the Paragraph, then print it
PrintBuf();
ClearBuf();
Found = 0;
}
else { //not 2 CRs so add the ch to buffer
AddCh(Ch);
if (! Found) { //If we already have a match, no need to look again
if ( srchst[SrchIndex] == '?' || //Wild card?
Ch == srchst[SrchIndex] || //lowercase match?
Ch == SRCHST[SrchIndex]) { //uppercase match?
SrchIndex ++; //check next character
if (srchst[SrchIndex] == 0) { /* if end of srchst, we have a match */
SrchIndex = 0; //reset for next test
Found = 1;
//printf("bingo!");
}
}
else //No match
SrchIndex = 0;
}
}
} while (! BufOverflow); //do; an exit is provided with break at feof
} //else, do it
if (Found == 1) //If a match still pending then print it
PrintBuf();
ClearBuf();
fclose(intext);
} //main