00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <sys/types.h>
00036 #include <regexp.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <stdio.h>
00040 #include <unistd.h>
00041
00042
00043 #define MATCH 0
00044 #define NO_MATCH 1
00045 #define FAILURE 2
00046
00047
00048 #define SET_FLAG(c) (flags[(c)-'a'] = 1)
00049 #define FLAG(c) (flags[(c)-'a'] != 0)
00050
00051 #define uppercase(c) (((unsigned) ((c) - 'A')) <= ('Z' - 'A'))
00052 #define downcase(c) ((c) - 'A' + 'a')
00053
00054
00055 static char *program;
00056 static char flags[26];
00057 static regexp *expression;
00058 static const char *rerr;
00059
00060
00061 extern int optind;
00062 extern char *optarg;
00063
00064
00065 _PROTOTYPE(int main, (int argc, char **argv));
00066 _PROTOTYPE(static int match, (FILE *input, char *label, char *filename));
00067 _PROTOTYPE(static char *get_line, (FILE *input));
00068 _PROTOTYPE(static char *map_nocase, (char *line));
00069 _PROTOTYPE(void regerror , (const char *s ) );
00070 _PROTOTYPE(static void tov8, (char *v8pattern, char *pattern));
00071
00072 int main(argc, argv)
00073 int argc;
00074 char *argv[];
00075 {
00076 int opt;
00077 int egrep=0;
00078 char *pattern;
00079 char *v8pattern;
00080 int exit_status = NO_MATCH;
00081 int file_status;
00082 FILE *input;
00083
00084 program = argv[0];
00085 if (strlen(program)>=5 && strcmp(program+strlen(program)-5,"egrep")==0) egrep=1;
00086 memset(flags, 0, sizeof(flags));
00087 pattern = NULL;
00088
00089
00090 while ((opt = getopt(argc, argv, "e:cilnsv")) != EOF) {
00091 if (opt == '?')
00092 exit_status = FAILURE;
00093 else
00094 if (opt == 'e')
00095 pattern = optarg;
00096 else
00097 SET_FLAG(opt);
00098 }
00099
00100
00101 if ((exit_status == FAILURE) || (optind == argc && pattern == NULL)) {
00102 fprintf(stderr,"Usage: %s [-cilnsv] [-e] expression [file ...]\n",program);
00103 exit(FAILURE);
00104 }
00105
00106
00107 if (pattern == NULL)
00108 pattern = argv[optind++];
00109
00110
00111 if (FLAG('i')) {
00112 char *p;
00113 for (p = pattern; *p != '\0'; p++) {
00114 if (uppercase(*p))
00115 *p = downcase(*p);
00116 }
00117 }
00118
00119 if (!egrep) {
00120 if ((v8pattern=malloc(2*strlen(pattern)))==(char*)0) {
00121 fprintf(stderr,"%s: out of memory\n");
00122 exit(FAILURE);
00123 }
00124 tov8(v8pattern,pattern);
00125 } else v8pattern=pattern;
00126
00127 rerr=(char*)0;
00128 if ((expression = regcomp(v8pattern)) == NULL) {
00129 fprintf(stderr,"%s: bad regular expression",program);
00130 if (rerr) fprintf(stderr," (%s)",rerr);
00131 fprintf(stderr,"\n");
00132 exit(FAILURE);
00133 }
00134
00135
00136 if (optind == argc) {
00137 exit_status = match(stdin, (char *) NULL, "<stdin>");
00138 }
00139 else
00140 if (optind + 1 == argc) {
00141 if (strcmp(argv[optind], "-") == 0) {
00142 exit_status = match(stdin, (char *) NULL, "-");
00143 } else {
00144 if ((input = fopen(argv[optind], "r")) == NULL) {
00145 fprintf(stderr, "%s: couldn't open %s\n",
00146 program, argv[optind]);
00147 exit_status = FAILURE;
00148 }
00149 else {
00150 exit_status = match(input, (char *) NULL, argv[optind]);
00151 }
00152 }
00153 }
00154 else
00155 while (optind < argc) {
00156 if (strcmp(argv[optind], "-") == 0) {
00157 file_status = match(stdin, "-", "-");
00158 } else {
00159 if ((input = fopen(argv[optind], "r")) == NULL) {
00160 fprintf(stderr, "%s: couldn't open %s\n",
00161 program, argv[optind]);
00162 exit_status = FAILURE;
00163 } else {
00164 file_status = match(input, argv[optind], argv[optind]);
00165 fclose(input);
00166 }
00167 }
00168 if (exit_status != FAILURE)
00169 exit_status &= file_status;
00170 ++optind;
00171 }
00172 return(exit_status);
00173 }
00174
00175
00176
00177
00178
00179
00180
00181 static int match(input, label, filename)
00182 FILE *input;
00183 char *label;
00184 char *filename;
00185 {
00186 char *line, *testline;
00187 long int lineno = 0;
00188 long int matchcount = 0;
00189 int status = NO_MATCH;
00190
00191 if (FLAG('s') || FLAG('l')) {
00192 while ((line = get_line(input)) != NULL) {
00193 testline = FLAG('i') ? map_nocase(line) : line;
00194 if (regexec(expression, testline, 1)) {
00195 status = MATCH;
00196 break;
00197 }
00198 }
00199 if (FLAG('l'))
00200 if ((!FLAG('v') && status == MATCH) ||
00201 ( FLAG('v') && status == NO_MATCH))
00202 puts(filename);
00203 return status;
00204 }
00205
00206 while ((line = get_line(input)) != NULL) {
00207 ++lineno;
00208 testline = FLAG('i') ? map_nocase(line) : line;
00209 if (regexec(expression, testline, 1)) {
00210 status = MATCH;
00211 if (!FLAG('v')) {
00212 if (label != NULL)
00213 printf("%s:", label);
00214 if (FLAG('n'))
00215 printf("%ld:", lineno);
00216 if (!FLAG('c')) puts(line);
00217 matchcount++;
00218 }
00219 } else {
00220 if (FLAG('v')) {
00221 if (label != NULL)
00222 printf("%s:", label);
00223 if (FLAG('n'))
00224 printf("%ld:", lineno);
00225 if (!FLAG('c')) puts(line);
00226 matchcount++;
00227 }
00228 }
00229 }
00230 if (FLAG('c')) printf("%ld\n", matchcount);
00231 return status;
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 #define FIRST_BUFFER (size_t)256
00243
00244 static char *buf = NULL;
00245 static size_t buf_size = 0;
00246
00247 static char *get_line(input)
00248 FILE *input;
00249 {
00250 int n;
00251 register char *bp;
00252 register int c;
00253 char *new_buf;
00254 size_t new_size;
00255
00256 if (buf_size == 0) {
00257 if ((buf = (char *) malloc(FIRST_BUFFER)) == NULL) {
00258 fprintf(stderr,"%s: not enough memory\n",program);
00259 exit(FAILURE);
00260 }
00261 buf_size = FIRST_BUFFER;
00262 }
00263
00264 bp = buf;
00265 n = buf_size;
00266 while (1) {
00267 while (--n > 0 && (c = getc(input)) != EOF) {
00268 if (c == '\n') {
00269 *bp = '\0';
00270 return buf;
00271 }
00272 *bp++ = c;
00273 }
00274 if (c == EOF)
00275 return (ferror(input) || bp == buf) ? NULL : buf;
00276 new_size = buf_size << 1;
00277 if ((new_buf = (char *) realloc(buf, new_size)) == NULL) {
00278 fprintf(stderr, "%s: line too long - truncated\n", program);
00279 while ((c = getc(input)) != EOF && c != '\n') ;
00280 *bp = '\0';
00281 return buf;
00282 } else {
00283 bp = new_buf + (buf_size - 1);
00284 n = buf_size + 1;
00285 buf = new_buf;
00286 buf_size = new_size;
00287 }
00288 }
00289 }
00290
00291
00292
00293
00294
00295
00296
00297 static char *map_nocase(line)
00298 char *line;
00299 {
00300 static char *mapped=(char*)0;
00301 static size_t map_size = 0;
00302 char *mp;
00303
00304 if (map_size < buf_size) {
00305 if ((mapped=realloc(mapped,map_size=buf_size)) == NULL) {
00306 fprintf(stderr,"%s: not enough memory\n",program);
00307 exit(FAILURE);
00308 }
00309 }
00310
00311 mp = mapped;
00312 do {
00313 *mp++ = uppercase(*line) ? downcase(*line) : *line;
00314 } while (*line++ != '\0');
00315
00316 return mapped;
00317 }
00318
00319
00320
00321
00322
00323
00324 static void tov8(char *v8, char *basic)
00325 {
00326 while (*basic) switch (*basic)
00327 {
00328 case '?':
00329 case '+':
00330 case '|':
00331 case '(':
00332 case ')':
00333 {
00334 *v8++='\\';
00335 *v8++=*basic++;
00336 break;
00337 }
00338 case '\\':
00339 {
00340 switch (*(basic+1))
00341 {
00342 case '?':
00343 case '+':
00344 case '|':
00345 case '(':
00346 case ')':
00347 {
00348 *v8++=*++basic;
00349 ++basic;
00350 break;
00351 }
00352 case '\0':
00353 {
00354 *v8++=*basic++;
00355 break;
00356 }
00357 default:
00358 {
00359 *v8++=*basic++;
00360 *v8++=*basic++;
00361 }
00362 }
00363 break;
00364 }
00365 default:
00366 {
00367 *v8++=*basic++;
00368 }
00369 }
00370 *v8++='\0';
00371 }
00372
00373
00374
00375 void regerror(s)
00376 const char *s;
00377 {
00378 rerr=s;
00379 }