source: trunk/src/gcc/fastjar/jargrep.c@ 37

Last change on this file since 37 was 37, checked in by bird, 22 years ago

use xregex to avoid linking trouble

  • Property cvs2svn:cvs-rev set to 1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 21.9 KB
Line 
1/*
2 jargrep.c - main functions for jargrep utility
3 Copyright (C) 2002 Free Software Foundation
4 Copyright (C) 1999, 2000 Bryan Burns
5 Copyright (C) 2000 Cory Hollingsworth
6
7 Parts of this program are base on Bryan Burns work with fastjar
8 Copyright (C) 1999.
9
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2
13 of the License, or (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23*/
24
25/* Id: jargrep.c,v 1.5 2002/01/03 04:57:56 rodrigc Exp
26
27Log: jargrep.c,v
28Revision 1.5 2002/01/03 04:57:56 rodrigc
292001-01-02 Craig Rodrigues <rodrigc@gcc.gnu.org>
30
31 PR bootstrap/5117
32 * configure.in (AC_CHECK_HEADERS): Check for stdlib.h.
33 * Makefile.am: Move grepjar to bin_PROGRAMS.
34 * config.h.in: Regenerated.
35 * Makefile.in: Regenerated.
36 * aclocal.m4: Regenerated.
37 * jargrep.c: Eliminate some signed/unsigned and default
38 uninitialized warnings. Use HAVE_STDLIB_H instead of
39 STDC_HEADERS macro.
40 * jartool.c: Likewise.
41 * compress.c: Likewise.
42
43Revision 1.4 2000/12/15 18:45:09 tromey
44 * jargrep.c: Include getopt.h if it exists.
45 (optind): Declare.
46 * configure, config.h: Rebuilt.
47 * configure.in: Check for getopt.h.
48
49Revision 1.3 2000/12/14 18:45:35 ghazi
50Warning fixes:
51
52 * compress.c: Include stdlib.h and compress.h.
53 (rcsid): Delete.
54 (report_str_error): Make static.
55 (ez_inflate_str): Delete unused variable. Add parens in if-stmt.
56 (hrd_inflate_str): Likewise.
57
58 * compress.h (init_compression, end_compression, init_inflation,
59 end_inflation): Prototype void arguments.
60
61 * dostime.c (rcsid): Delete.
62
63 * jargrep.c: Include ctype.h, stdlib.h, zlib.h and compress.h.
64 Make functions static. Cast ctype function argument to `unsigned
65 char'. Add parens in if-stmts. Constify.
66 (Usage): Change into a macro.
67 (jargrep): Remove unused parameter.
68
69 * jartool.c: Constify. Add parens in if-stmts. Align
70 signed/unsigned char pointers in functions calls using casts.
71 (rcsid): Delete.
72 (list_jar): Fix printf format specifier.
73 (usage): Chop long string into bits. Reformat.
74
75 * pushback.c (rcsid): Delete.
76
77Revision 1.2 2000/12/11 02:59:55 apbianco
782000-12-10 Robert Lipe <robertlipe@usa.net>
79
80 * jargrep.c (jargrep): Added null statement after case.
81
822000-12-10 Alexandre Petit-Bianco <apbianco@cygnus.com>
83
84 * Makefile: Removed.
85 * Makefile.in: Rebuilt with `-i' and `--enable-foreign'.
86
87(http://gcc.gnu.org/ml/gcc/2000-12/msg00294.html)
88
89Revision 1.1 2000/12/09 03:08:23 apbianco
902000-12-08 Alexandre Petit-Bianco <apbianco@cygnus.com>
91
92 * fastjar: Imported.
93
94Revision 1.8 2000/09/13 14:02:02 cory
95Reformatted some of the code to more closly match the layout of the orriginal
96fastjar utility.
97
98Revision 1.7 2000/09/12 22:29:36 cory
99Jargrep now seems to do what I want it to do. Performs properly on Linux x86,
100will test some other platforms later.
101
102
103*/
104
105#include "config.h"
106#include <stdio.h>
107#include <unistd.h>
108/* bird: use xregex to avoid linking trouble
109 * #include <regex.h>
110 */
111#include <xregex.h>
112#include <errno.h>
113#include <string.h>
114#include <sys/types.h>
115#include <sys/stat.h>
116#include <fcntl.h>
117#include <ctype.h>
118#ifdef HAVE_STDLIB_H
119#include <stdlib.h>
120#endif
121#include "jargrep.h"
122#include "jartool.h"
123#include "pushback.h"
124#include "zipfile.h"
125#include "zlib.h"
126#include "compress.h"
127#include <getopt.h>
128
129void version(void);
130void help(const char *name);
131
132#define Usage "Usage: %s [-bcinsw] <-e PATTERN | PATTERN> FILE ...\n"
133
134/*
135Function name: opt_valid
136arg: options Bitfield flag that contains the command line options of grepjar.
137purpose: To guard agains the occurance of certain incompatible flags being used
138together.
139returns: TRUE if options are valid, FALSE otherwise.
140*/
141
142static int opt_valid(int options) {
143 int retflag;
144
145 if((options & JG_PRINT_COUNT) &&
146 (options & (JG_PRINT_BYTEOFFSET | JG_PRINT_LINE_NUMBER)))
147 {
148 retflag = FALSE;
149 }
150 else retflag = TRUE;
151
152 return retflag;
153}
154
155/*
156Function name: create_regexp
157args: regstr String containing the uncompiled regular expression. This may be the
158 expression as is passed in through argv.
159 options This is the flag containing the commandline options that have been
160 parsed by getopt.
161purpose: Handle the exception handling involved with setting upt a new regular
162expression.
163returns: Newly allocated compile regular expression ready to be used in an regexec call.
164*/
165
166static regex_t *create_regexp(const char *regstr, int options) {
167 regex_t *exp;
168 int errcode;
169 int msgsize;
170 char *errmsg;
171
172 if((exp = (regex_t *) malloc(sizeof(regex_t))))
173 {
174 if((errcode = regcomp(exp, regstr, (options & JG_IGNORE_CASE) ? REG_ICASE : 0))) {
175 fprintf(stderr, "regcomp of regex failed,\n");
176 if((errmsg = (char *) malloc(msgsize = regerror(errcode, exp, NULL, 0) + 1))) {
177 regerror(errcode, exp, errmsg, msgsize);
178 fprintf(stderr, "Error: %s\n", errmsg);
179 free(exp);
180 free(errmsg);
181 exit(1);
182 }
183 else {
184 fprintf(stderr, "Malloc of errmsg failed.\n");
185 fprintf(stderr, "Error: %s\n", strerror(errno));
186 free(exp);
187 exit(1);
188 }
189 }
190 }
191 else {
192 fprintf(stderr, "Malloc of regex failed,\n");
193 fprintf(stderr, "Error: %s\n", strerror(errno));
194 exit(1);
195 }
196
197 return exp;
198}
199
200/*
201Function name: check_sig
202args: scratch Pointer to array of bytes containing signature.
203 pbf Pointer to push back handle for jar file.
204purpose: Verify that checksum is correct.
205returns: 0, 1, or 2. 0 means we are ready to read embedded file information. 1 means
206we have read beyound the embedded file list and can exit knowing we have read all the
207relevent information. 2 means we still haven't reached embdedded file list and need to
208do some more reading.
209*/
210static int check_sig(ub1 *scratch, pb_file *pbfp) {
211 ub4 signature;
212 int retflag = 0;
213
214 signature = UNPACK_UB4(scratch, 0);
215
216#ifdef DEBUG
217 printf("signature is %x\n", signature);
218#endif
219 if(signature == 0x08074b50){
220#ifdef DEBUG
221 printf("skipping data descriptor\n");
222#endif
223 pb_read(pbfp, scratch, 12);
224 retflag = 2;
225 } else if(signature == 0x02014b50){
226#ifdef DEBUG
227 printf("Central header reached.. we're all done!\n");
228#endif
229 retflag = 1;
230 }else if(signature != 0x04034b50){
231 printf("Ick! %#x\n", signature);
232 retflag = 1;
233 }
234
235 return retflag;
236}
237
238/*
239Function name: decd_siz
240args csize Pointer to embedded file's compressed size.
241 usize Pointer to embedded file's uncmpressed size.
242 fnlen Pointer to embedded file's file name length.
243 elfen Pointer to length of extra fields in jar file.
244 flags Pointer to bitmapped flags.
245 method Pointer to indicator of storage method of embedded file.
246 file_header Pointer to string containing the above values to be unbacked.
247Purpose: Unpack the series of values from file_header.
248*/
249
250static void decd_siz(ub4 *csize, ub4 *usize, ub2 *fnlen, ub2 *eflen, ub2 *flags, ub2 *method, ub1 *file_header) {
251 *csize = UNPACK_UB4(file_header, LOC_CSIZE);
252#ifdef DEBUG
253 printf("Compressed size is %u\n", *csize);
254#endif
255
256 *usize = UNPACK_UB4(file_header, LOC_USIZE);
257#ifdef DEBUG
258 printf("Uncompressed size is %u\n", *usize);
259#endif
260
261 *fnlen = UNPACK_UB2(file_header, LOC_FNLEN);
262#ifdef DEBUG
263 printf("Filename length is %hu\n", *fnlen);
264#endif
265
266 *eflen = UNPACK_UB2(file_header, LOC_EFLEN);
267#ifdef DEBUG
268 printf("Extra field length is %hu\n", *eflen);
269#endif
270
271 *flags = UNPACK_UB2(file_header, LOC_EXTRA);
272#ifdef DEBUG
273 printf("Flags are %#hx\n", *flags);
274#endif
275
276 *method = UNPACK_UB2(file_header, LOC_COMP);
277#ifdef DEBUG
278 printf("Compression method is %#hx\n", *method);
279#endif
280
281}
282
283/*
284Function name: new_filename
285args: pbf Pointer to push back file handle. Used for reading input file.
286 len Length of file name to be read.
287purpose: Read in the embedded file name from jar file.
288returns: Pointer to newly allocated string containing file name.
289*/
290
291static char *new_filename(pb_file *pbf, ub4 len) {
292 char *filename;
293
294 if(!(filename = (char *) malloc(len + 1))) {
295 fprintf(stderr, "Malloc failed of filename\n");
296 fprintf(stderr, "Error: %s\n", strerror(errno));
297 }
298 pb_read(pbf, filename, len);
299 filename[len] = '\0';
300
301#ifdef DEBUG
302 printf("filename is %s\n", filename);
303#endif
304
305 return filename;
306}
307
308/*
309Funtion name: read_string
310args: pbf Pointer to push back file handle. Used for reading input file.
311 size Size of embedded file in bytes.
312purpose: Create a string containing the contents of the embedded noncompressed file.
313returns: Pointer to newly allocated string containing embedded file contents.
314*/
315
316static char *read_string(pb_file *pbf, int size) {
317 char *page;
318
319 if((page = (char *) malloc(size + 1))) {
320 pb_read(pbf, page, size);
321 page[size] = '\0';
322 }
323 else {
324 fprintf(stderr, "Malloc of page buffer failed.\n");
325 fprintf(stderr, "Error: %s\n", strerror(errno));
326 exit(1);
327 }
328
329 return page;
330}
331
332/*
333Function name: extract_line
334args: stream String containing the full contents of a file which is to be substringed
335 in order to provide line representing our grep output.
336 begin Index into stream which regular expression first matches.
337 end Index into stream which end of match to the regular expression.
338 b Pointer to the index of what will be the beginning of the line when
339 string is returned. Used for -b option.
340purpose: Create a string that can be printed by jargrep from the long string stream.
341The matching line that is printed out by jargrep is generated by this function.
342returns: Pointer to newly allocated string containing matched expression.
343*/
344
345static char *extract_line(const char *stream, regoff_t begin, regoff_t end, int *b) {
346 int e;
347 int length;
348 char *retstr;
349
350 for(*b = begin; *b >= 0 && !iscntrl((unsigned char)stream[*b]); (*b)--);
351 (*b)++;
352 for(e = end; stream[e] == '\t' || !iscntrl((unsigned char)stream[e]); e++);
353 length = e - *b;
354 if((retstr = (char *) malloc(length + 1))) {
355 sprintf(retstr, "%d:", *b);
356 strncpy(retstr, &(stream[*b]), length);
357 retstr[length] = '\0';
358 }
359 else {
360 fprintf(stderr, "Malloc failed of output string.\n");
361 fprintf(stderr, "Error: %s\n", strerror(errno));
362 exit(1);
363 }
364
365 return retstr;
366}
367
368/*
369Function name: chk_wrd
370args: exp Pointer to compiled POSIX style regular expression of search target.
371 str String known to contain at least one match of exp.
372purpose: Verify that the occurance of the regular expression in str occurs as a whole
373word and not a substring of another word.
374returns: TRUE if it is a word, FALSE of it is a substring.
375*/
376
377static int chk_wrd(regex_t *exp, const char *str) {
378 int wrd_fnd = FALSE;
379 int regflag;
380 int frnt_ok;
381 int bck_ok;
382 const char *str2;
383 regmatch_t match;
384
385 str2 = str;
386 frnt_ok = bck_ok = FALSE;
387 while(!wrd_fnd && !(regflag = regexec(exp, str2, 1, &match, 0))) {
388 if(!match.rm_so && (str2 == str)) frnt_ok = TRUE;
389 else if(!isalnum((unsigned char)str2[match.rm_so - 1])
390 && str2[match.rm_so - 1] != '_')
391 frnt_ok = TRUE;
392 else frnt_ok = FALSE;
393 if(frnt_ok) {
394 if(str2[match.rm_eo] == '\0') bck_ok = TRUE;
395 else if(!isalnum((unsigned char)str2[match.rm_eo])
396 && str2[match.rm_eo] != '_')
397 bck_ok = TRUE;
398 else bck_ok = FALSE;
399 }
400 wrd_fnd = frnt_ok && bck_ok;
401 str2 = &(str2[match.rm_eo]);
402 }
403
404 return wrd_fnd;
405}
406
407/*
408Function name: prnt_mtchs
409args: exp Pointer to compiled POSIX style regular expression of search target.
410 filename String containing the name of the embedded file which matches have
411 been found in.
412 stream String containing the processed contents of the embedded jar file
413 represended with filename.
414 pmatch Array of regmatch_t matches into stream.
415 nl_offset Array of offsets of '\n' characters in stream. May be NULL if -n is
416 not set on command line.
417 num Number of matches in pmatch array.
418 lines Number of lines in file. Not set if -n is not set on command line.
419 options Bitwise flag containing flags set to represent the command line
420 options.
421purpose: Control output of jargrep. Output is controlled by which options have been
422set at the command line.
423*/
424
425static void prnt_mtchs(regex_t *exp, const char *filename, const char *stream, regmatch_t *pmatch, regmatch_t *nl_offset, int num, int lines, int options) {
426 int i;
427 int j = 0;
428 int ln_cnt;
429 int begin;
430 int o_begin;
431 char *str;
432
433 o_begin = -1;
434 ln_cnt = 0;
435 for(i = 0; i < num; i++) {
436 str = extract_line(stream, pmatch[i].rm_so, pmatch[i].rm_eo, &begin);
437 if(begin > o_begin) {
438 if(!(options & JG_WORD_EXPRESSIONS) || chk_wrd(exp, str)) {
439 ln_cnt++;
440 if(!(options & JG_PRINT_COUNT)) {
441 printf("%s:", filename);
442 if(options & JG_PRINT_LINE_NUMBER) {
443 for(; j < lines && nl_offset[j].rm_so < begin; j++);
444 printf("%d:", j + 1);
445 }
446 if(options & JG_PRINT_BYTEOFFSET) printf("%d:", begin);
447 printf("%s\n", str);
448 }
449 }
450 }
451 o_begin = begin;
452 free(str);
453 }
454 if(options & JG_PRINT_COUNT) printf("%s:%d\n", filename, ln_cnt);
455}
456
457/*
458Function name: check_crc
459args: pbf Pointer to pushback file pointer for jar file.
460 stream String containing the non modified contents fo the extraced file entry.
461 usize Size of file in bytes.
462purpose: Verify the CRC matches that as what is stored in the jar file.
463*/
464
465static void check_crc(pb_file *pbf, const char *stream, ub4 usize) {
466 ub4 crc=0;
467 ub4 lcrc;
468 ub1 scratch[16];
469
470 crc = crc32(crc, NULL, 0);
471 crc = crc32(crc, (const unsigned char *)stream, usize);
472 if(pb_read(pbf, scratch, 16) != 16) {
473 perror("read");
474 exit(1);
475 }
476 if(UNPACK_UB4(scratch, 0) != 0x08074b50) {
477 fprintf(stderr, "Error! Missing data descriptor!\n");
478 exit(1);
479 }
480 lcrc = UNPACK_UB4(scratch, 4);
481 if(crc != lcrc){
482 fprintf(stderr, "Error! CRCs do not match! Got %x, expected %x\n",
483 crc, lcrc);
484 exit(1);
485 }
486}
487
488/*
489Function name mk_ascii
490args: stream String that contains the contents of the extraced file entry.
491 usize String size.
492purpose: Make certain that the contents of the file are ASCII, not binary. This
493permits grepping of binary files as well by converting non ASCII and control characters
494into '\n'.
495*/
496
497static void mk_ascii(char *stream, size_t usize) {
498 size_t i;
499
500 for(i = 0; i < usize; i++)
501 if(stream[i] != '\t'
502 && (iscntrl((unsigned char)stream[i])
503 || (unsigned char) stream[i] >= 128))
504 stream[i] = '\n';
505}
506
507/*
508Funtion name: fnd_match
509args: exp Pointer to compiled POSIX style regular expression of search target.
510 str_stream String that contains the contents of the extracted file entry.
511 i Pointer to counter and index of matches.
512purpose: Search str_stream for occurances of the regular expression exp and create
513an array of matches.
514returns: Pointer to newly allocated array of regmatch_t which gives indexes to start
515and end of matches. NULL is returned upon no matches found.
516*/
517
518static regmatch_t *fnd_match(regex_t *exp, const char *str_stream, int *i) {
519 int regflag;
520 regmatch_t match;
521 regmatch_t *match_array;
522 regmatch_t *tmp;
523
524 match_array = NULL;
525 for(*i = 0, regflag = regexec(exp, str_stream, 1, &match, 0); !regflag;
526 regflag = regexec(exp, &(str_stream[match.rm_eo]), 1, &match, 0), (*i)++)
527 {
528 if((tmp = (regmatch_t *)
529 realloc(match_array, sizeof(regmatch_t) * ((*i) + 1))))
530 {
531 match_array = tmp;
532 if(*i) {
533 match.rm_so += match_array[(*i) - 1].rm_eo;
534 match.rm_eo += match_array[(*i) - 1].rm_eo;
535 }
536 match_array[*i] = match;
537 }
538 else {
539 fprintf(stderr, "Realloc of match_array failed.\n");
540 fprintf(stderr, "Error: %s\n", strerror(errno));
541 exit(1);
542 }
543 }
544
545 return match_array;
546}
547
548/*
549Function name: cont_grep
550args: exp Pointer to compiled POSIX style regular expression of search target.
551 nl_exp Pointer to compiled POSIX style regular expression of newlines. This
552 argument is NULL unless the -n option is used on the command line.
553 fd File descriptor of the jar file being grepped.
554 pbf Pointer to pushback file style file stream. This is for use with
555 the pushback.c file io funtions.
556 options Bitwise flag containing flags set to represent the command line options.
557purpose: This function handles single entries in an open jar file. The header is
558read and then the embeded file is extracted and grepped.
559returns: FALSE upon failure, TRUE otherwise.
560*/
561
562static int cont_grep(regex_t *exp, regex_t *nl_exp, int fd, pb_file *pbf, int options) {
563 int retflag = TRUE;
564 int i;
565 int j;
566 ub4 csize;
567 ub4 usize;
568 ub2 fnlen;
569 ub2 eflen;
570 ub2 flags;
571 ub2 method;
572 ub1 file_header[30];
573 char *filename;
574 char *str_stream;
575 regmatch_t *match_array;
576 regmatch_t *nl_offsets=0;
577
578 if(pb_read(pbf, (file_header + 4), 26) != 26) {
579 perror("read");
580 retflag = FALSE;
581 }
582 else {
583 decd_siz(&csize, &usize, &fnlen, &eflen, &flags, &method, file_header);
584 filename = new_filename(pbf, fnlen);
585 lseek(fd, eflen, SEEK_CUR);
586 if(filename[fnlen - 1] != '/') {
587 str_stream = (method == 8 || (flags & 0x0008)) ?
588 (char *) inflate_string(pbf, &csize, &usize) :
589 read_string(pbf, csize);
590 if(flags & 0x008) check_crc(pbf, str_stream, usize);
591 mk_ascii(str_stream, usize);
592 match_array = fnd_match(exp, str_stream, &i);
593 if((options & JG_PRINT_LINE_NUMBER) && i)
594 nl_offsets = fnd_match(nl_exp, str_stream, &j);
595 prnt_mtchs(exp, filename, str_stream, match_array, nl_offsets, i, j, options);
596 if(match_array) free(match_array);
597 free(str_stream);
598 }
599 free(filename);
600 retflag = TRUE;
601 }
602
603 return retflag;
604}
605
606/*
607Funtion name: jargrep
608args: exp Pointer to compiled POSIX style regular expression of search target.
609 nl_exp Pointer to compiled regular expression for newlines or NULL. Only set
610 if -n option is present at command line.
611 jarfile Filename of jar file to be searched.
612 options Bitwise flag containing flags set to represent the command line options.
613purpose: Open jar file. Check signatures. When right signature is found go to deeper
614grep routine.
615*/
616
617static void jargrep(regex_t *exp, regex_t *nl_exp, const char *jarfile, int options){
618 int fd;
619 int floop = TRUE;
620 pb_file pbf;
621 ub1 scratch[16];
622
623 if((fd = open(jarfile, O_RDONLY)) == -1) {
624 if(!(options & JG_SUPRESS_ERROR))
625 fprintf(stderr, "Error reading file '%s': %s\n", jarfile, strerror(errno));
626 }
627 else {
628 pb_init(&pbf, fd);
629
630 do {
631 if(pb_read(&pbf, scratch, 4) != 4) {
632 perror("read");
633 floop = FALSE;
634 }
635 else {
636 switch (check_sig(scratch, &pbf)) {
637 case 0:
638 floop = cont_grep(exp, nl_exp, fd, &pbf, options);
639 break;
640 case 1:
641 floop = FALSE;
642 break;
643 case 2:
644 /* fall through continue */
645 ;
646 }
647 }
648 } while(floop);
649 }
650}
651
652/* This is used to mark options with no short value. */
653#define LONG_OPT(Num) ((Num) + 128)
654
655#define OPT_HELP LONG_OPT (0)
656
657static const struct option option_vec[] =
658{
659 { "help", no_argument, NULL, OPT_HELP },
660 { "version", no_argument, NULL, 'V' },
661 { NULL, no_argument, NULL, 0 }
662};
663
664/*
665Funtion Name: main
666args: argc number of in coming args.
667 argv array of strings.
668purpose: Entry point of the program. Parse command line arguments and set options.
669Set up regular expressions. Call grep routines for each file as input.
670returns: 1 on error 0 on success.
671*/
672
673int main(int argc, char **argv) {
674 int c;
675 int retval = 0;
676 int fileindex;
677 int options = 0;
678 regex_t *regexp;
679 regex_t *nl_exp = NULL;
680 char *regexpstr = NULL;
681
682 while((c = getopt_long(argc, argv, "bce:insVw",
683 option_vec, NULL)) != -1) {
684 switch(c) {
685 case 'b':
686 options |= JG_PRINT_BYTEOFFSET;
687 break;
688 case 'c':
689 options |= JG_PRINT_COUNT;
690 break;
691 case 'e':
692 if(!(regexpstr = (char *) malloc(strlen(optarg) + 1))) {
693 fprintf(stderr, "Malloc failure.\n");
694 fprintf(stderr, "Error: %s\n", strerror(errno));
695 exit(1);
696 }
697 strcpy(regexpstr, optarg);
698 break;
699 case 'i':
700 options |= JG_IGNORE_CASE;
701 break;
702 case 'n':
703 options |= JG_PRINT_LINE_NUMBER;
704 break;
705 case 's':
706 options |= JG_SUPRESS_ERROR;
707 break;
708 case 'v':
709 options |= JG_INVERT;
710 break;
711 case 'V':
712 version ();
713 break;
714 case 'w':
715 options |= JG_WORD_EXPRESSIONS;
716 break;
717 case OPT_HELP:
718 help(argv[0]);
719 break;
720 default:
721 fprintf(stderr, Usage, argv[0]);
722 exit(1);
723 }
724 }
725 if(!regexpstr){
726 if(((argc - optind) >= 2)) {
727 regexpstr = argv[optind];
728 fileindex = optind + 1;
729 }
730 else {
731 fprintf(stderr, "Invalid arguments.\n");
732 fprintf(stderr, Usage, argv[0]);
733 exit(1);
734 }
735 }
736 else if((argc - optind) == 1) {
737 fileindex = optind;
738 }
739 else {
740 fprintf(stderr, "Invalid arguments.\n");
741 fprintf(stderr, Usage, argv[0]);
742 exit(1);
743 }
744
745 if(opt_valid(options)) {
746 regexp = create_regexp(regexpstr, options);
747 if(options & JG_PRINT_LINE_NUMBER) nl_exp = create_regexp("\n", 0);
748 init_inflation();
749 for(; fileindex < argc; fileindex++)
750 jargrep(regexp, nl_exp, argv[fileindex], options);
751 regfree(regexp);
752 if(options & JG_PRINT_LINE_NUMBER) regfree(nl_exp);
753 }
754 else {
755 retval = 1;
756 fprintf(stderr, "Error: Invalid combination of options.\n");
757 }
758
759 return retval;
760}
761
762void help(const char *filename)
763{
764 printf (Usage, filename);
765 printf ("\
766\n\
767Search files in a jar file for a pattern.\n\
768\n\
769 -b print byte offset of match\n\
770 -c print number of matches\n\
771 -i compare case-insensitively\n\
772 -n print line number of each match\n\
773 -s suppress error messages\n\
774 -w force PATTERN to match only whole words\n\
775 -e PATTERN use PATTERN as regular exprssion\n\
776");
777
778 exit (0);
779}
780
781void version ()
782{
783 printf("grepjar (%s) %s\n\n", PACKAGE, VERSION);
784 printf("Copyright 1999, 2000, 2001 Bryan Burns\n");
785 printf("Copyright 2000 Cory Hollingsworth\n");
786 printf("Copyright 2002 Free Software Foundation\n");
787 printf("\
788This is free software; see the source for copying conditions. There is NO\n\
789warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
790 exit (0);
791}
Note: See TracBrowser for help on using the repository browser.