home *** CD-ROM | disk | FTP | other *** search
- /* `filter', v. 2.1 Latest mod: 12:30 Jun 8 1994
- A `grep'-like text searcher for multiple simultaneous keyword tests
-
- Copyright 1994 by Joel Polowin, Department of Chemistry, Queen's University,
- Kingston, Ontario, Canada. Permission granted for free use and distribution;
- I want credit/blame for writing it. E-mail: polowin@silicon.chem.queensu.ca,
- polowinj@qucdn.queensu.ca, Joel.Polowin@p4.f107.n249.z1.fidonet.org .
-
- If you see something wrong with it or it fails to work, PLEASE let me know!
- */
-
- #define LENGTH 601 /* 1 more than max # characters */
- #define ARGS 2000
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
-
- void syntax ()
- {
- fprintf(stderr,"Syntax: filter [filename] [filename ...] string [string ...]\n where");
- fprintf(stderr," each string (max. of %d) is a term to be searched for",ARGS);
- fprintf(stderr," in lines (max.\n %d chars) in file",LENGTH-1);
- fprintf(stderr," `filename', prefixed by one of the following characters:\n");
- fprintf(stderr," + to show lines which contain string\n");
- fprintf(stderr," - to show lines which do not contain string\n");
- fprintf(stderr," = to show lines which contain string, case sensitive\n");
- fprintf(stderr," _ (underscore) to show lines which do not contain string,\n");
- fprintf(stderr," case sensitive\n\n");
- fprintf(stderr,"A string as above may be further prefixed with the letter 'o' to\n");
- fprintf(stderr," print the line if the current OR the preceding condition is true.");
- fprintf(stderr,"\nA string including blanks and the prefix may be enclosed in");
- fprintf(stderr," double quotes.\nStrings beginning with one of `$&^' designate");
- fprintf(stderr," file expansion; see filter21.doc.\n\nExamples:\n filter armorial");
- fprintf(stderr," =Vert +argent -gules _Or -azure -purpur +foil > tempfile.txt\n");
- fprintf(stderr," type temp1.txt | filter +aardvark \042o+winged pig\042 ");
- fprintf(stderr,"o+wombat \042_|B|\042\n\nFilter utility v.2.1 (C) 1994 by Joel");
- fprintf(stderr," Polowin, Chem. Dept., Queen's University,\nKingston. Permission");
- fprintf(stderr," granted for free use; I want credit/blame for writing it.\n");
- fprintf(stderr,"polowin@silicon.chem.queensu.ca, polowinj@qucdn.queensu.ca\n");
- exit(1);
- }
-
- void main(argc,argv)
- int argc;
- char *argv[];
- {
- char line[LENGTH],lowline[LENGTH];
- FILE *infile;
- int i,j,k,l,test,firststring,nostring,lowcase;
- void syntax();
- void strlow();
- char flag[ARGS+1],orflag[ARGS+1];
- char *myargv[ARGS+1];
- int blocksize;
- char *prefix,*filename;
-
- firststring=0;
- for(i=1; i<argc; i++)
- {
- if(*argv[i]=='=' || *argv[i]=='+' || *argv[i]=='-' || *argv[i]=='_')
- {
- test=*argv[i];
- for(j=1; test==*(argv[i]+j); j++)
- ;
- if(j%2 && firststring==0)
- firststring=i;
- argv[i]+=j/2;
- }
- }
-
- if(firststring==0)
- {
- fprintf(stderr,"Must specify a search string.\n");
- syntax();
- }
-
- nostring=argc-firststring;
- if(nostring>ARGS)
- {
- fprintf(stderr,"Too many search strings specified.\n");
- syntax();
- }
-
- lowcase=0;
-
- for (i=0; i<ARGS+1; i++) orflag[i]=0;
-
- blocksize=0;
- for (i=firststring; i<argc; i++) blocksize+=strlen(argv[i])+1;
- if (NULL==(myargv[1]=malloc(blocksize)))
- {
- fprintf(stderr,"Can't allocate memory for string storage.\n");
- exit(1);
- }
- strcpy(myargv[1],argv[firststring]);
-
- for(i=2; i<=nostring; i++)
- {
- myargv[i]=myargv[i-1]+strlen(myargv[i-1])+1;
- strcpy(myargv[i],argv[i+firststring-1]);
- }
-
- for (i=1; i<=nostring; i++)
- {
- j=0;
- switch(*myargv[i])
- {
- case '+':
- strlow(myargv[i]);
- lowcase=1;
- case '=':
- flag[i]=1;
- break;
- case '-':
- strlow(myargv[i]);
- lowcase=1;
- case '_':
- flag[i]=0;
- break;
- case 'O':
- case 'o':
- orflag[i-1]=1;
- myargv[i]++;
- i--;
- j=1;
- break;
- default:
- fprintf(stderr,"Error in string no. %d: %s\n",i-1,myargv[i]);
- syntax();
- }
-
- if((!j) && (((test=*(myargv[i]+1))=='$') || (test=='&') || (test=='^')))
- {
- for(j=1; test==*(myargv[i]+1+j); j++)
- ; /* count identical flag chars */
-
- l=j/2;
-
- for (k=0; *(myargv[i]+k)!='\0'; k++) /* shift string to delete */
- *(myargv[i]+k+1)=*(myargv[i]+k+l+1); /* half of flag chars */
-
- if(j%2) /* an odd number of flag chars: expand file */
- {
- if(test=='^')
- {
- prefix="";
- orflag[i-1]=0;
- }
- else
- {
- switch(*myargv[i]) /* determine prefix for expanded terms */
- { /* from current prefix and expansion type */
- case '+':
- if(test=='$') prefix="o+";
- else prefix="+";
- break;
- case '=':
- if(test=='$') prefix="o=";
- else prefix="=";
- break;
- case '-':
- if(test=='$') prefix="-";
- else prefix="o-";
- break;
- case '_':
- if(test=='$') prefix="_";
- else prefix="o_";
- break;
- default:
- fprintf(stderr,"Bugger-up in program!\n");
- exit(1);
- }
- }
-
- filename=myargv[i]+2;
-
- if(!(infile=fopen(filename,"r")))
- {
- fprintf(stderr,"Can't open search-term file %s\n",filename);
- exit(1);
- }
-
- if(test!='^') test=*myargv[i]; /* prefix of current term */
-
- blocksize=0; /* figure out how much memory to allocate */
- for(j=0;;j++) /* for new terms */
- {
- if(NULL==fgets(line,LENGTH,infile)) break;
- if(LENGTH==strlen(line)+1) fprintf(stderr,
- "* Warning: truncated search term file %s line\n%s\n",
- filename,line);
- if(line[strlen(line)-1]=='\n') line[strlen(line)-1]='\0';
- blocksize+=strlen(line)+1;
- }
-
- if (j==0)
- {
- fprintf(stderr,"* Warning: empty search term file %s\n",
- filename);
- j=1;
- }
-
- blocksize+=j*strlen(prefix);
- rewind(infile);
-
- if(nostring+j-1>ARGS)
- {
- fprintf(stderr,"File expansion gives too many terms (%d max)\n",
- ARGS);
- exit(1);
- }
-
- for(k=nostring; k>i; k--) /* shift old myargv to make room */
- myargv[k+j-1]=myargv[k];
-
- if(NULL==(myargv[i]=malloc(blocksize)))
- {
- fprintf(stderr,"Can't allocate memory for search term expansion.\n");
- exit(1);
- }
-
- for(k=0;k<j;k++)
- {
- fgets(line,LENGTH,infile);
- if(line[strlen(line)-1]=='\n') line[strlen(line)-1]='\0';
- if(k==0)
- {
- if(test=='^') strcpy(myargv[i],line);
- else
- {
- *myargv[i]=test;
- strcpy(myargv[i]+1,line);
- }
- }
- else
- {
- myargv[i+k]=myargv[i+k-1]+strlen(myargv[i+k-1])+1;
- strcpy(myargv[i+k],prefix);
- strcat(myargv[i+k],line);
- }
- }
-
- fclose(infile);
- nostring+=j-1;
- i--;
- }
- }
- }
-
- k=0;
- do
- {
- k++;
- if(firststring==1) infile=stdin;
- else
- if(!(infile=fopen(argv[k],"r")))
- {
- fprintf(stderr,"Can't open file %s for reading.\n",argv[k]);
- syntax();
- }
- l=0;
-
- for (;;)
- {
- if(NULL==fgets(line,LENGTH,infile)) break;
- if(LENGTH==strlen(line)+1) fprintf(stderr,"* Warning: truncated line \n%s\n",line);
- if(lowcase) strlow(strcpy(lowline,line));
- for(i=1; i<=nostring; i++)
- {
- test=0;
- switch(*myargv[i])
- {
- case '=':
- case '_':
- if(NULL!=strstr(line,(myargv[i]+1))) test=1;
- break;
- default:
- if(NULL!=strstr(lowline,(myargv[i]+1))) test=1;
- break;
- }
- if(test!=flag[i] && orflag[i]==0) break;
- if(test==flag[i])
- while(orflag[i]==1) i++;
- }
- if(i>nostring)
- {
- if(firststring>2 && l==0)
- {
- printf("File %s:\n",argv[k]);
- l=1;
- }
- printf("%s",line);
- }
- }
- if(infile!=stdin) fclose(infile);
- }
- while(k<firststring-1);
- exit(0);
- }
-
- void strlow(string)
- char *string;
- {
- while (*string!='\0')
- {
- *string=tolower(*string);
- string++;
- }
- }
-
-
- /* Revision history:
-
- Version 1.0 September 1992.
-
- 1.1 Sep '92 fixed minor bugs
- 1.2 Sep '92 added 'or'-linking to keywords
- 1.4 Oct '92 fixed a minor error in string lengths, added size DEFINEs
- 1.5 Jan '94 increased string lengths, fixed a Stupid Newbie Error re:
- assumption that *argv[] was writeable
- 2.0 Feb '94 added search-term file expansion and multiple text file
- capability, including wildcards when system permits
- 2.1 Jun '94 added null-prefix search-term files and term-file `rewind'
-
- */
-