+
+extern int grep_main(int argc, char **argv)
+{
+ int opt;
+#ifdef BB_FEATURE_GREP_CONTEXT
+ char *junk;
+#endif
+
+#ifdef BB_FEATURE_CLEAN_UP
+ /* destroy command strings on exit */
+ if (atexit(destroy_regexes) == -1)
+ perror_msg_and_die("atexit");
+#endif
+
+ /* do normal option parsing */
+ while ((opt = getopt(argc, argv, "iHhlnqvsce:f:"
+#ifdef BB_FEATURE_GREP_CONTEXT
+"A:B:C:"
+#endif
+)) > 0) {
+ switch (opt) {
+ case 'i':
+ reflags |= REG_ICASE;
+ break;
+ case 'l':
+ print_files_with_matches++;
+ break;
+ case 'H':
+ print_filename++;
+ break;
+ case 'h':
+ print_filename--;
+ break;
+ case 'n':
+ print_line_num++;
+ break;
+ case 'q':
+ be_quiet++;
+ break;
+ case 'v':
+ invert_search++;
+ break;
+ case 's':
+ suppress_err_msgs++;
+ break;
+ case 'c':
+ print_match_counts++;
+ break;
+ case 'e':
+ add_regex(optarg);
+ break;
+ case 'f':
+ load_regexes_from_file(optarg);
+ break;
+#ifdef BB_FEATURE_GREP_CONTEXT
+ case 'A':
+ lines_after = strtoul(optarg, &junk, 10);
+ if(*junk != '\0')
+ error_msg_and_die("invalid context length argument");
+ break;
+ case 'B':
+ lines_before = strtoul(optarg, &junk, 10);
+ if(*junk != '\0')
+ error_msg_and_die("invalid context length argument");
+ before_buf = (char **)calloc(lines_before, sizeof(char *));
+ break;
+ case 'C':
+ lines_after = lines_before = strtoul(optarg, &junk, 10);
+ if(*junk != '\0')
+ error_msg_and_die("invalid context length argument");
+ before_buf = (char **)calloc(lines_before, sizeof(char *));
+ break;
+#endif /* BB_FEATURE_GREP_CONTEXT */
+ default:
+ show_usage();
+ }
+ }
+
+ /* if we didn't get a pattern from a -e and no command file was specified,
+ * argv[optind] should be the pattern. no pattern, no worky */
+ if (nregexes == 0) {
+ if (argv[optind] == NULL)
+ show_usage();
+ else {
+ add_regex(argv[optind]);
+ optind++;
+ }
+ }
+
+ /* sanity checks */
+ if (print_match_counts || be_quiet || print_files_with_matches) {
+ print_line_num = 0;
+#ifdef BB_FEATURE_GREP_CONTEXT
+ lines_before = 0;
+ lines_after = 0;
+#endif
+ }
+
+ /* argv[(optind)..(argc-1)] should be names of file to grep through. If
+ * there is more than one file to grep, we will print the filenames */
+ if ((argc-1) - (optind) > 0)
+ print_filename++;
+
+ /* If no files were specified, or '-' was specified, take input from
+ * stdin. Otherwise, we grep through all the files specified. */
+ if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) {
+ grep_file(stdin);
+ }
+ else {
+ int i;
+ FILE *file;
+ for (i = optind; i < argc; i++) {
+ cur_file = argv[i];
+ file = fopen(cur_file, "r");
+ if (file == NULL) {
+ if (!suppress_err_msgs)
+ perror_msg("%s", cur_file);
+ }
+ else {
+ grep_file(file);
+ fclose(file);
+ }
+ }
+ }
+
+ return !matched; /* invert return value 0 = success, 1 = failed */
+}