Diff for /embedaddon/pcre/pcregrep.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2012/02/21 23:50:25 version 1.1.1.3, 2012/10/09 09:19:17
Line 104  enum { DEE_READ, DEE_SKIP }; Line 104  enum { DEE_READ, DEE_SKIP };
   
 enum { EL_LF, EL_CR, EL_CRLF, EL_ANY, EL_ANYCRLF };  enum { EL_LF, EL_CR, EL_CRLF, EL_ANY, EL_ANYCRLF };
   
   /* Binary file options */
   
   enum { BIN_BINARY, BIN_NOMATCH, BIN_TEXT };
   
 /* In newer versions of gcc, with FORTIFY_SOURCE set (the default in some  /* In newer versions of gcc, with FORTIFY_SOURCE set (the default in some
 environments), a warning is issued if the value of fwrite() is ignored.  environments), a warning is issued if the value of fwrite() is ignored.
 Unfortunately, casting to (void) does not suppress the warning. To get round  Unfortunately, casting to (void) does not suppress the warning. To get round
Line 147  static int  pattern_count = 0; Line 151  static int  pattern_count = 0;
 static pcre **pattern_list = NULL;  static pcre **pattern_list = NULL;
 static pcre_extra **hints_list = NULL;  static pcre_extra **hints_list = NULL;
   
   static char *file_list = NULL;
 static char *include_pattern = NULL;  static char *include_pattern = NULL;
 static char *exclude_pattern = NULL;  static char *exclude_pattern = NULL;
 static char *include_dir_pattern = NULL;  static char *include_dir_pattern = NULL;
Line 159  static pcre *exclude_dir_compiled = NULL; Line 164  static pcre *exclude_dir_compiled = NULL;
   
 static int after_context = 0;  static int after_context = 0;
 static int before_context = 0;  static int before_context = 0;
   static int binary_files = BIN_BINARY;
 static int both_context = 0;  static int both_context = 0;
 static int bufthird = PCREGREP_BUFSIZE;  static int bufthird = PCREGREP_BUFSIZE;
 static int bufsize = 3*PCREGREP_BUFSIZE;  static int bufsize = 3*PCREGREP_BUFSIZE;
Line 196  static BOOL utf8 = FALSE; Line 202  static BOOL utf8 = FALSE;
 /* Structure for options and list of them */  /* Structure for options and list of them */
   
 enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_LONGNUMBER,  enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_LONGNUMBER,
       OP_OP_NUMBER, OP_PATLIST };       OP_OP_NUMBER, OP_PATLIST, OP_BINFILES };
   
 typedef struct option_item {  typedef struct option_item {
   int type;    int type;
Line 225  used to identify them. */ Line 231  used to identify them. */
 #define N_M_LIMIT_REC  (-14)  #define N_M_LIMIT_REC  (-14)
 #define N_BUFSIZE      (-15)  #define N_BUFSIZE      (-15)
 #define N_NOJIT        (-16)  #define N_NOJIT        (-16)
   #define N_FILE_LIST    (-17)
   #define N_BINARY_FILES (-18)
   
 static option_item optionlist[] = {  static option_item optionlist[] = {
  { OP_NODATA,     N_NULL,   NULL,              "",              "  terminate options" },  { OP_NODATA,     N_NULL,   NULL,              "",              "terminate options" },
   { OP_NODATA,     N_HELP,   NULL,              "help",          "display this help and exit" },    { OP_NODATA,     N_HELP,   NULL,              "help",          "display this help and exit" },
   { OP_NUMBER,     'A',      &after_context,    "after-context=number", "set number of following context lines" },    { OP_NUMBER,     'A',      &after_context,    "after-context=number", "set number of following context lines" },
     { OP_NODATA,     'a',      NULL,              "text",          "treat binary files as text" },
   { OP_NUMBER,     'B',      &before_context,   "before-context=number", "set number of prior context lines" },    { OP_NUMBER,     'B',      &before_context,   "before-context=number", "set number of prior context lines" },
     { OP_BINFILES,   N_BINARY_FILES, NULL,        "binary-files=word", "set treatment of binary files" },
   { OP_NUMBER,     N_BUFSIZE,&bufthird,         "buffer-size=number", "set processing buffer size parameter" },    { OP_NUMBER,     N_BUFSIZE,&bufthird,         "buffer-size=number", "set processing buffer size parameter" },
   { OP_OP_STRING,  N_COLOUR, &colour_option,    "color=option",  "matched text color option" },    { OP_OP_STRING,  N_COLOUR, &colour_option,    "color=option",  "matched text color option" },
   { OP_OP_STRING,  N_COLOUR, &colour_option,    "colour=option", "matched text colour option" },    { OP_OP_STRING,  N_COLOUR, &colour_option,    "colour=option", "matched text colour option" },
Line 241  static option_item optionlist[] = { Line 251  static option_item optionlist[] = {
   { OP_PATLIST,    'e',      NULL,              "regex(p)=pattern", "specify pattern (may be used more than once)" },    { OP_PATLIST,    'e',      NULL,              "regex(p)=pattern", "specify pattern (may be used more than once)" },
   { OP_NODATA,     'F',      NULL,              "fixed-strings", "patterns are sets of newline-separated strings" },    { OP_NODATA,     'F',      NULL,              "fixed-strings", "patterns are sets of newline-separated strings" },
   { OP_STRING,     'f',      &pattern_filename, "file=path",     "read patterns from file" },    { OP_STRING,     'f',      &pattern_filename, "file=path",     "read patterns from file" },
     { OP_STRING,     N_FILE_LIST, &file_list,     "file-list=path","read files to search from file" },
   { OP_NODATA,     N_FOFFSETS, NULL,            "file-offsets",  "output file offsets, not text" },    { OP_NODATA,     N_FOFFSETS, NULL,            "file-offsets",  "output file offsets, not text" },
   { OP_NODATA,     'H',      NULL,              "with-filename", "force the prefixing filename on output" },    { OP_NODATA,     'H',      NULL,              "with-filename", "force the prefixing filename on output" },
   { OP_NODATA,     'h',      NULL,              "no-filename",   "suppress the prefixing filename on output" },    { OP_NODATA,     'h',      NULL,              "no-filename",   "suppress the prefixing filename on output" },
     { OP_NODATA,     'I',      NULL,              "",              "treat binary files as not matching (ignore)" },
   { OP_NODATA,     'i',      NULL,              "ignore-case",   "ignore case distinctions" },    { OP_NODATA,     'i',      NULL,              "ignore-case",   "ignore case distinctions" },
 #ifdef SUPPORT_PCREGREP_JIT  #ifdef SUPPORT_PCREGREP_JIT
   { OP_NODATA,     N_NOJIT,  NULL,              "no-jit",        "do not use just-in-time compiler optimization" },    { OP_NODATA,     N_NOJIT,  NULL,              "no-jit",        "do not use just-in-time compiler optimization" },
Line 1044  char *lastmatchrestart = NULL; Line 1056  char *lastmatchrestart = NULL;
 char *ptr = main_buffer;  char *ptr = main_buffer;
 char *endptr;  char *endptr;
 size_t bufflength;  size_t bufflength;
   BOOL binary = FALSE;
 BOOL endhyphenpending = FALSE;  BOOL endhyphenpending = FALSE;
 BOOL input_line_buffered = line_buffered;  BOOL input_line_buffered = line_buffered;
 FILE *in = NULL;                    /* Ensure initialized */  FILE *in = NULL;                    /* Ensure initialized */
Line 1091  else Line 1104  else
   
 endptr = main_buffer + bufflength;  endptr = main_buffer + bufflength;
   
   /* Unless binary-files=text, see if we have a binary file. This uses the same
   rule as GNU grep, namely, a search for a binary zero byte near the start of the
   file. */
   
   if (binary_files != BIN_TEXT)
     {
     binary =
       memchr(main_buffer, 0, (bufflength > 1024)? 1024 : bufflength) != NULL;
     if (binary && binary_files == BIN_NOMATCH) return 1;
     }
   
 /* Loop while the current pointer is not at the end of the file. For large  /* Loop while the current pointer is not at the end of the file. For large
 files, endptr will be at the end of the buffer when we are in the middle of the  files, endptr will be at the end of the buffer when we are in the middle of the
 file, but ptr will never get there, because as soon as it gets over 2/3 of the  file, but ptr will never get there, because as soon as it gets over 2/3 of the
Line 1207  while (ptr < endptr) Line 1231  while (ptr < endptr)
   
     if (count_only) count++;      if (count_only) count++;
   
       /* When handling a binary file and binary-files==binary, the "binary"
       variable will be set true (it's false in all other cases). In this
       situation we just want to output the file name. No need to scan further. */
   
       else if (binary)
         {
         fprintf(stdout, "Binary file %s matches\n", filename);
         return 0;
         }
   
     /* If all we want is a file name, there is no need to scan any more lines      /* If all we want is a file name, there is no need to scan any more lines
     in the file. */      in the file. */
   
Line 1584  gzFile ingz = NULL; Line 1618  gzFile ingz = NULL;
 BZFILE *inbz2 = NULL;  BZFILE *inbz2 = NULL;
 #endif  #endif
   
#if defined SUPPORT_LIBZ || defined SUPPORT_LIBZ2#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2
 int pathlen;  int pathlen;
 #endif  #endif
   
Line 1667  skipping was not requested. The scan proceeds. If this Line 1701  skipping was not requested. The scan proceeds. If this
 argument at top level, we don't show the file name, unless we are only showing  argument at top level, we don't show the file name, unless we are only showing
 the file name, or the filename was forced (-H). */  the file name, or the filename was forced (-H). */
   
#if defined SUPPORT_LIBZ || defined SUPPORT_LIBZ2#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2
 pathlen = (int)(strlen(pathname));  pathlen = (int)(strlen(pathname));
 #endif  #endif
   
Line 1843  for (op = optionlist; op->one_char != 0; op++) Line 1877  for (op = optionlist; op->one_char != 0; op++)
   
   if (strchr(op->long_name, '_') != NULL) continue;    if (strchr(op->long_name, '_') != NULL) continue;
   
  if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, "   ");  if (op->one_char > 0 && (op->long_name)[0] == 0)
  n = 31 - printf("  %s --%s", s, op->long_name);    n = 31 - printf("  -%c", op->one_char);
   else
     {
     if (op->one_char > 0) sprintf(s, "-%c,", op->one_char);
       else strcpy(s, "   ");
     n = 31 - printf("  %s --%s", s, op->long_name);
     }
 
   if (n < 1) n = 1;    if (n < 1) n = 1;
  printf("%.*s%s\n", n, "                     ", op->help_text);  printf("%.*s%s\n", n, "                           ", op->help_text);
   }    }
   
 printf("\nNumbers may be followed by K or M, e.g. --buffer-size=100K.\n");  printf("\nNumbers may be followed by K or M, e.g. --buffer-size=100K.\n");
 printf("The default value for --buffer-size is %d.\n", PCREGREP_BUFSIZE);  printf("The default value for --buffer-size is %d.\n", PCREGREP_BUFSIZE);
printf("When reading patterns from a file instead of using a command line option,\n");printf("When reading patterns or file names from a file, trailing white\n");
printf("trailing white space is removed and blank lines are ignored.\n");printf("space is removed and blank lines are ignored.\n");
 printf("There is a maximum of %d patterns, each of maximum size %d bytes.\n",  printf("There is a maximum of %d patterns, each of maximum size %d bytes.\n",
   MAX_PATTERN_COUNT, PATBUFSIZE);    MAX_PATTERN_COUNT, PATBUFSIZE);
   
Line 1877  switch(letter) Line 1918  switch(letter)
   case N_LBUFFER: line_buffered = TRUE; break;    case N_LBUFFER: line_buffered = TRUE; break;
   case N_LOFFSETS: line_offsets = number = TRUE; break;    case N_LOFFSETS: line_offsets = number = TRUE; break;
   case N_NOJIT: study_options &= ~PCRE_STUDY_JIT_COMPILE; break;    case N_NOJIT: study_options &= ~PCRE_STUDY_JIT_COMPILE; break;
     case 'a': binary_files = BIN_TEXT; break;
   case 'c': count_only = TRUE; break;    case 'c': count_only = TRUE; break;
   case 'F': process_options |= PO_FIXED_STRINGS; break;    case 'F': process_options |= PO_FIXED_STRINGS; break;
   case 'H': filenames = FN_FORCE; break;    case 'H': filenames = FN_FORCE; break;
     case 'I': binary_files = BIN_NOMATCH; break;
   case 'h': filenames = FN_NONE; break;    case 'h': filenames = FN_NONE; break;
   case 'i': options |= PCRE_CASELESS; break;    case 'i': options |= PCRE_CASELESS; break;
   case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break;    case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break;
Line 2325  for (i = 1; i < argc; i++) Line 2368  for (i = 1; i < argc; i++)
     patterns[cmd_pattern_count++] = option_data;      patterns[cmd_pattern_count++] = option_data;
     }      }
   
     /* Handle OP_BINARY_FILES */
   
     else if (op->type == OP_BINFILES)
       {
       if (strcmp(option_data, "binary") == 0)
         binary_files = BIN_BINARY;
       else if (strcmp(option_data, "without-match") == 0)
         binary_files = BIN_NOMATCH;
       else if (strcmp(option_data, "text") == 0)
         binary_files = BIN_TEXT;
       else
         {
         fprintf(stderr, "pcregrep: unknown value \"%s\" for binary-files\n",
           option_data);
         pcregrep_exit(usage(2));
         }
       }
   
   /* Otherwise, deal with single string or numeric data values. */    /* Otherwise, deal with single string or numeric data values. */
   
   else if (op->type != OP_NUMBER && op->type != OP_LONGNUMBER &&    else if (op->type != OP_NUMBER && op->type != OP_LONGNUMBER &&
Line 2695  if (include_dir_pattern != NULL) Line 2756  if (include_dir_pattern != NULL)
     }      }
   }    }
   
/* If there are no further arguments, do the business on stdin and exit. *//* If a file that contains a list of files to search has been specified, read
 it line by line and search the given files. Otherwise, if there are no further
 arguments, do the business on stdin and exit. */
   
if (i >= argc)if (file_list != NULL)
   {    {
     char buffer[PATBUFSIZE];
     FILE *fl;
     if (strcmp(file_list, "-") == 0) fl = stdin; else
       {
       fl = fopen(file_list, "rb");
       if (fl == NULL)
         {
         fprintf(stderr, "pcregrep: Failed to open %s: %s\n", file_list,
           strerror(errno));
         goto EXIT2;
         }
       }
     while (fgets(buffer, PATBUFSIZE, fl) != NULL)
       {
       int frc;
       char *end = buffer + (int)strlen(buffer);
       while (end > buffer && isspace(end[-1])) end--;
       *end = 0;
       if (*buffer != 0)
         {
         frc = grep_or_recurse(buffer, dee_action == dee_RECURSE, FALSE);
         if (frc > 1) rc = frc;
           else if (frc == 0 && rc == 1) rc = 0;
         }
       }
     if (fl != stdin) fclose (fl);
     }
   
   /* Do this only if there was no file list (and no file arguments). */
   
   else if (i >= argc)
     {
   rc = pcregrep(stdin, FR_PLAIN, stdin_name,    rc = pcregrep(stdin, FR_PLAIN, stdin_name,
     (filenames > FN_DEFAULT)? stdin_name : NULL);      (filenames > FN_DEFAULT)? stdin_name : NULL);
   goto EXIT;    goto EXIT;
   }    }
   
/* Otherwise, work through the remaining arguments as files or directories./* After handling file-list or if there are remaining arguments, work through
Pass in the fact that there is only one argument at top level - this suppressesthem as files or directories. Pass in the fact that there is only one argument
the file name if the argument is not a directory and filenames are notat top level - this suppresses the file name if the argument is not a directory
otherwise forced. */and filenames are not otherwise forced. */
   
only_one_at_top = i == argc - 1;   /* Catch initial value of i */only_one_at_top = i == argc - 1 && file_list == NULL;
   
 for (; i < argc; i++)  for (; i < argc; i++)
   {    {

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>