|
|
1.1 root 1: #define MAIN 1
2: #include <ctype.h>
3: #include "re.h"
4: #include "lre.h"
5: #include "hdr.h"
6:
7: /* handle void* which didn't exist prior to ANSI C and C++ */
8: #if defined(__STDC__) || defined(c_plusplus) || defined(__cplusplus)
9: # define VOID void
10: #else
11: # define VOID char
12: #endif
13:
14: static enum { gre, grep, egrep, fgrep } whoami = gre;
15: static char fullopts[] = "e:f:1bcEFGhilLnsvx";
16: static char *opts = fullopts+4; /* start in after last : */
17:
18: static void
19: usage(void)
20: {
21: EPR "usage: %s [ -%s ] [ -e pattern ] [ -f file ] [ pattern ] [ file ] ...\n", progname, opts);
22: exit(2);
23: }
24:
25: #ifdef PROFILING
26: short profb[50000];
27: #endif
28:
29: main(int argc, char **argv)
30: {
31: register c;
32: int errflg = 0;
33: char *input = 0, *finput = 0;
34: int k, sval;
35: unsigned char map[256];
36: int foundsome = 0;
37: PROCFN procfn;
38: RDFN rdfn;
39: MATCHFN matchfn;
40: VOID *pat;
41:
42: #ifdef PROFILING
43: { extern etext(); monitor((int (*)())2, etext, profb, ((int)etext) - 2+12+2400, 300); }
44: #endif
45:
46: /*re_debug=20;/**/
47: /*
48: determine if we are to be restricted to compatability mode
49: */
50: if(progname = strrchr(argv[0], '/'))
51: progname++;
52: else
53: progname = argv[0];
54: #ifdef PLAN9
55: if(strcmp(progname, "ogrep") == 0)
56: #else
57: if(strcmp(progname, "grep") == 0)
58: #endif
59: whoami = grep;
60: else if(strcmp(progname, "egrep") == 0)
61: whoami = egrep;
62: else if(strcmp(progname, "fgrep") == 0)
63: whoami = fgrep;
64: offsetunit = (whoami == gre)? 1 : 1024; /* test before -[FGE] */
65: /*
66: read the options; decide legality after we know what we are doing.
67: the options are split so we can maintain the usage line
68: in one place. note the only option we have to be wary of
69: is -f (not grep)
70: */
71: while((c = getopt(argc, argv, fullopts)) != -1)
72: switch(c)
73: {
74: case '1': oneflag = 1; break;
75: case 'b': bflag = 1; break;
76: case 'c': cflag = 1; break;
77: case 'e': if(input){
78: EPR "%s: only one -e arg allowed\n", progname);
79: errflg = 1;
80: }
81: input = optarg; break;
82: case 'E': whoami = egrep; break;
83: case 'f': if(input){
84: EPR "%s: only one -f arg allowed\n", progname);
85: errflg = 1;
86: }
87: finput = optarg; break;
88: case 'F': whoami = fgrep; break;
89: case 'G': whoami = grep; break;
90: case 'h': hflag = 1; break;
91: case 'i': iflag = 1; break;
92: case 'l': lflag = 1; break;
93: case 'L': Lflag = 1; break;
94: case 'n': nflag = 1; break;
95: case 's': sflag = 1; break;
96: case 'v': vflag = 1; break;
97: case 'x': xflag = 1; break;
98: case '?': errflg = 1; break;
99: }
100: if(errflg)
101: usage();
102: argv += optind;
103: /*
104: check for bad flag combinations
105: */
106: if(finput && (whoami == grep)){
107: EPR "%s: cannot use -f with grep\n", progname);
108: exit(2);
109: }
110: if(finput && input){
111: EPR "%s: cannot use -f with -e\n", progname);
112: exit(2);
113: }
114: if(!input && !finput){
115: input = *argv++;
116: if(input == 0)
117: usage();
118: }
119: /*
120: character mapping ?
121: */
122: for(k = 0; k < 256; k++)
123: map[k] = k;
124: if(iflag)
125: for(k = 'A'; k <= 'Z'; k++)
126: map[k] = tolower(k);
127: /*
128: in the interests of readability, fob off grep-type specific
129: handling to separate functions. setting bmfn means using
130: bmfind; similiarly cwfn means use cwfind
131:
132: rules:
133: lnum needs be maintained only if nflag.
134: nbytes needs be maintained only if bflag.
135: for -[s1lL], do a longjmp(env).
136: for -c, increment nmatch.
137: */
138: switch(whoami)
139: {
140: case gre: dogre(greparse, input, finput, map, &procfn, &pat, &rdfn, &matchfn); break;
141: case grep: dogre(grepparse, input, finput, map, &procfn, &pat, &rdfn, &matchfn); break;
142: case fgrep: dofgrep(input, finput, map, &procfn, &pat, &rdfn, &matchfn); break;
143: case egrep: dogre(egrepparse, input, finput, map, &procfn, &pat, &rdfn, &matchfn); break;
144: }
145: /*
146: do generic flag handling
147: */
148: prname = !hflag && *argv && argv[1];
149: /*
150: do file arguments now! for uniformity, no args = '-'
151: */
152: if(!*argv)
153: *--argv = "-";
154: for(; curfile = *argv++; close(ifd)){
155: if(strcmp(curfile, "-") == 0)
156: ifd = 0;
157: else if((ifd = open(curfile, 0)) < 0){
158: EPR "%s: ", progname);
159: perror(curfile);
160: errflg = 2;
161: continue;
162: }
163: if(sflag && foundsome)
164: continue; /* don't need to scan */
165: lnum = nmatch = nbytes = 0;
166: longlinewarned = 0;
167: if((sval = setjmp(env)) == 0)
168: if((*procfn)(pat, rdfn, matchfn) < 0){
169: EPR "%s: ", progname);
170: perror(curfile);
171: errflg = 2;
172: continue;
173: }
174: if((lflag && sval) || (Lflag && !sval))
175: PR "%s\n", curfile);
176: if(cflag){
177: if(prname)
178: PR "%s:", curfile);
179: PR "%ld\n", nmatch);
180: }
181: if(nmatch)
182: foundsome = 1;
183: }
184: exit(errflg? errflg : (foundsome == 0));
185: /*NOTREACHED*/
186: }
187:
188: void
189: re_error(char *s)
190: {
191: EPR "%s: %s\n", progname, s);
192: exit(2);
193: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.