/[pcre]/code/trunk/pcregrep.c
ViewVC logotype

Diff of /code/trunk/pcregrep.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 283 by ph10, Fri Dec 7 19:59:19 2007 UTC revision 515 by ph10, Tue May 4 09:12:25 2010 UTC
# Line 6  Line 6 
6  its pattern matching. On a Unix or Win32 system it can recurse into  its pattern matching. On a Unix or Win32 system it can recurse into
7  directories.  directories.
8    
9             Copyright (c) 1997-2007 University of Cambridge             Copyright (c) 1997-2010 University of Cambridge
10    
11  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
12  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 55  POSSIBILITY OF SUCH DAMAGE. Line 55  POSSIBILITY OF SUCH DAMAGE.
55  #include <unistd.h>  #include <unistd.h>
56  #endif  #endif
57    
58    #ifdef SUPPORT_LIBZ
59    #include <zlib.h>
60    #endif
61    
62    #ifdef SUPPORT_LIBBZ2
63    #include <bzlib.h>
64    #endif
65    
66  #include "pcre.h"  #include "pcre.h"
67    
68  #define FALSE 0  #define FALSE 0
# Line 63  POSSIBILITY OF SUCH DAMAGE. Line 71  POSSIBILITY OF SUCH DAMAGE.
71  typedef int BOOL;  typedef int BOOL;
72    
73  #define MAX_PATTERN_COUNT 100  #define MAX_PATTERN_COUNT 100
74    #define OFFSET_SIZE 99
75    
76  #if BUFSIZ > 8192  #if BUFSIZ > 8192
77  #define MBUFTHIRD BUFSIZ  #define MBUFTHIRD BUFSIZ
# Line 74  typedef int BOOL; Line 83  typedef int BOOL;
83  output. The order is important; it is assumed that a file name is wanted for  output. The order is important; it is assumed that a file name is wanted for
84  all values greater than FN_DEFAULT. */  all values greater than FN_DEFAULT. */
85    
86  enum { FN_NONE, FN_DEFAULT, FN_ONLY, FN_NOMATCH_ONLY, FN_FORCE };  enum { FN_NONE, FN_DEFAULT, FN_MATCH_ONLY, FN_NOMATCH_ONLY, FN_FORCE };
87    
88    /* File reading styles */
89    
90    enum { FR_PLAIN, FR_LIBZ, FR_LIBBZ2 };
91    
92  /* Actions for the -d and -D options */  /* Actions for the -d and -D options */
93    
# Line 91  enum { DEE_READ, DEE_SKIP }; Line 104  enum { DEE_READ, DEE_SKIP };
104    
105  enum { EL_LF, EL_CR, EL_CRLF, EL_ANY, EL_ANYCRLF };  enum { EL_LF, EL_CR, EL_CRLF, EL_ANY, EL_ANYCRLF };
106    
107    /* In newer versions of gcc, with FORTIFY_SOURCE set (the default in some
108    environments), a warning is issued if the value of fwrite() is ignored.
109    Unfortunately, casting to (void) does not suppress the warning. To get round
110    this, we use a macro that compiles a fudge. Oddly, this does not also seem to
111    apply to fprintf(). */
112    
113    #define FWRITE(a,b,c,d) if (fwrite(a,b,c,d)) {}
114    
115    
116    
117  /*************************************************  /*************************************************
# Line 127  static pcre_extra **hints_list = NULL; Line 148  static pcre_extra **hints_list = NULL;
148    
149  static char *include_pattern = NULL;  static char *include_pattern = NULL;
150  static char *exclude_pattern = NULL;  static char *exclude_pattern = NULL;
151    static char *include_dir_pattern = NULL;
152    static char *exclude_dir_pattern = NULL;
153    
154  static pcre *include_compiled = NULL;  static pcre *include_compiled = NULL;
155  static pcre *exclude_compiled = NULL;  static pcre *exclude_compiled = NULL;
156    static pcre *include_dir_compiled = NULL;
157    static pcre *exclude_dir_compiled = NULL;
158    
159  static int after_context = 0;  static int after_context = 0;
160  static int before_context = 0;  static int before_context = 0;
# Line 148  static BOOL invert = FALSE; Line 173  static BOOL invert = FALSE;
173  static BOOL line_offsets = FALSE;  static BOOL line_offsets = FALSE;
174  static BOOL multiline = FALSE;  static BOOL multiline = FALSE;
175  static BOOL number = FALSE;  static BOOL number = FALSE;
176    static BOOL omit_zero_count = FALSE;
177  static BOOL only_matching = FALSE;  static BOOL only_matching = FALSE;
178  static BOOL quiet = FALSE;  static BOOL quiet = FALSE;
179  static BOOL silent = FALSE;  static BOOL silent = FALSE;
# Line 169  typedef struct option_item { Line 195  typedef struct option_item {
195  /* Options without a single-letter equivalent get a negative value. This can be  /* Options without a single-letter equivalent get a negative value. This can be
196  used to identify them. */  used to identify them. */
197    
198  #define N_COLOUR    (-1)  #define N_COLOUR       (-1)
199  #define N_EXCLUDE   (-2)  #define N_EXCLUDE      (-2)
200  #define N_HELP      (-3)  #define N_EXCLUDE_DIR  (-3)
201  #define N_INCLUDE   (-4)  #define N_HELP         (-4)
202  #define N_LABEL     (-5)  #define N_INCLUDE      (-5)
203  #define N_LOCALE    (-6)  #define N_INCLUDE_DIR  (-6)
204  #define N_NULL      (-7)  #define N_LABEL        (-7)
205  #define N_LOFFSETS  (-8)  #define N_LOCALE       (-8)
206  #define N_FOFFSETS  (-9)  #define N_NULL         (-9)
207    #define N_LOFFSETS     (-10)
208    #define N_FOFFSETS     (-11)
209    
210  static option_item optionlist[] = {  static option_item optionlist[] = {
211    { OP_NODATA,    N_NULL,   NULL,              "",              "  terminate options" },    { OP_NODATA,    N_NULL,   NULL,              "",              "  terminate options" },
# Line 190  static option_item optionlist[] = { Line 218  static option_item optionlist[] = {
218    { 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" },
219    { OP_STRING,    'D',      &DEE_option,       "devices=action","how to handle devices, FIFOs, and sockets" },    { OP_STRING,    'D',      &DEE_option,       "devices=action","how to handle devices, FIFOs, and sockets" },
220    { OP_STRING,    'd',      &dee_option,       "directories=action", "how to handle directories" },    { OP_STRING,    'd',      &dee_option,       "directories=action", "how to handle directories" },
221    { OP_PATLIST,   'e',      NULL,              "regex(p)",      "specify pattern (may be used more than once)" },    { OP_PATLIST,   'e',      NULL,              "regex(p)=pattern", "specify pattern (may be used more than once)" },
222    { 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" },
223    { OP_STRING,    'f',      &pattern_filename, "file=path",     "read patterns from file" },    { OP_STRING,    'f',      &pattern_filename, "file=path",     "read patterns from file" },
224    { OP_NODATA,    N_FOFFSETS, NULL,            "file-offsets",  "output file offsets, not text" },    { OP_NODATA,    N_FOFFSETS, NULL,            "file-offsets",  "output file offsets, not text" },
225    { OP_NODATA,    'H',      NULL,              "with-filename", "force the prefixing filename on output" },    { OP_NODATA,    'H',      NULL,              "with-filename", "force the prefixing filename on output" },
# Line 210  static option_item optionlist[] = { Line 238  static option_item optionlist[] = {
238    { OP_NODATA,    'r',      NULL,              "recursive",     "recursively scan sub-directories" },    { OP_NODATA,    'r',      NULL,              "recursive",     "recursively scan sub-directories" },
239    { OP_STRING,    N_EXCLUDE,&exclude_pattern,  "exclude=pattern","exclude matching files when recursing" },    { OP_STRING,    N_EXCLUDE,&exclude_pattern,  "exclude=pattern","exclude matching files when recursing" },
240    { OP_STRING,    N_INCLUDE,&include_pattern,  "include=pattern","include matching files when recursing" },    { OP_STRING,    N_INCLUDE,&include_pattern,  "include=pattern","include matching files when recursing" },
241      { OP_STRING,    N_EXCLUDE_DIR,&exclude_dir_pattern, "exclude_dir=pattern","exclude matching directories when recursing" },
242      { OP_STRING,    N_INCLUDE_DIR,&include_dir_pattern, "include_dir=pattern","include matching directories when recursing" },
243  #ifdef JFRIEDL_DEBUG  #ifdef JFRIEDL_DEBUG
244    { OP_OP_NUMBER, 'S',      &S_arg,            "jeffS",         "replace matched (sub)string with X" },    { OP_OP_NUMBER, 'S',      &S_arg,            "jeffS",         "replace matched (sub)string with X" },
245  #endif  #endif
# Line 322  return isatty(fileno(stdout)); Line 352  return isatty(fileno(stdout));
352    
353  /* I (Philip Hazel) have no means of testing this code. It was contributed by  /* I (Philip Hazel) have no means of testing this code. It was contributed by
354  Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES  Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES
355  when it did not exist. David Byron added a patch that moved the #include of  when it did not exist. David Byron added a patch that moved the #include of
356  <windows.h> to before the INVALID_FILE_ATTRIBUTES definition rather than after.  <windows.h> to before the INVALID_FILE_ATTRIBUTES definition rather than after.
357  */  */
358    
359  #elif HAVE_WINDOWS_H  #elif HAVE_WINDOWS_H
# Line 791  if (after_context > 0 && lastmatchnumber Line 821  if (after_context > 0 && lastmatchnumber
821      if (printname != NULL) fprintf(stdout, "%s-", printname);      if (printname != NULL) fprintf(stdout, "%s-", printname);
822      if (number) fprintf(stdout, "%d-", lastmatchnumber++);      if (number) fprintf(stdout, "%d-", lastmatchnumber++);
823      pp = end_of_line(pp, endptr, &ellength);      pp = end_of_line(pp, endptr, &ellength);
824      fwrite(lastmatchrestart, 1, pp - lastmatchrestart, stdout);      FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
825      lastmatchrestart = pp;      lastmatchrestart = pp;
826      }      }
827    hyphenpending = TRUE;    hyphenpending = TRUE;
# Line 801  if (after_context > 0 && lastmatchnumber Line 831  if (after_context > 0 && lastmatchnumber
831    
832    
833  /*************************************************  /*************************************************
834    *   Apply patterns to subject till one matches   *
835    *************************************************/
836    
837    /* This function is called to run through all patterns, looking for a match. It
838    is used multiple times for the same subject when colouring is enabled, in order
839    to find all possible matches.
840    
841    Arguments:
842      matchptr    the start of the subject
843      length      the length of the subject to match
844      offsets     the offets vector to fill in
845      mrc         address of where to put the result of pcre_exec()
846    
847    Returns:      TRUE if there was a match
848                  FALSE if there was no match
849                  invert if there was a non-fatal error
850    */
851    
852    static BOOL
853    match_patterns(char *matchptr, size_t length, int *offsets, int *mrc)
854    {
855    int i;
856    for (i = 0; i < pattern_count; i++)
857      {
858      *mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, length, 0,
859        PCRE_NOTEMPTY, offsets, OFFSET_SIZE);
860      if (*mrc >= 0) return TRUE;
861      if (*mrc == PCRE_ERROR_NOMATCH) continue;
862      fprintf(stderr, "pcregrep: pcre_exec() error %d while matching ", *mrc);
863      if (pattern_count > 1) fprintf(stderr, "pattern number %d to ", i+1);
864      fprintf(stderr, "this text:\n");
865      FWRITE(matchptr, 1, length, stderr);   /* In case binary zero included */
866      fprintf(stderr, "\n");
867      if (error_count == 0 &&
868          (*mrc == PCRE_ERROR_MATCHLIMIT || *mrc == PCRE_ERROR_RECURSIONLIMIT))
869        {
870        fprintf(stderr, "pcregrep: error %d means that a resource limit "
871          "was exceeded\n", *mrc);
872        fprintf(stderr, "pcregrep: check your regex for nested unlimited loops\n");
873        }
874      if (error_count++ > 20)
875        {
876        fprintf(stderr, "pcregrep: too many errors - abandoned\n");
877        exit(2);
878        }
879      return invert;    /* No more matching; don't show the line again */
880      }
881    
882    return FALSE;  /* No match, no errors */
883    }
884    
885    
886    
887    /*************************************************
888  *            Grep an individual file             *  *            Grep an individual file             *
889  *************************************************/  *************************************************/
890    
# Line 812  be in the middle third most of the time, Line 896  be in the middle third most of the time,
896  "before" context printing.  "before" context printing.
897    
898  Arguments:  Arguments:
899    in           the fopened FILE stream    handle       the fopened FILE stream for a normal file
900                   the gzFile pointer when reading is via libz
901                   the BZFILE pointer when reading is via libbz2
902      frtype       FR_PLAIN, FR_LIBZ, or FR_LIBBZ2
903    printname    the file name if it is to be printed for each match    printname    the file name if it is to be printed for each match
904                 or NULL if the file name is not to be printed                 or NULL if the file name is not to be printed
905                 it cannot be NULL if filenames[_nomatch]_only is set                 it cannot be NULL if filenames[_nomatch]_only is set
906    
907  Returns:       0 if there was at least one match  Returns:       0 if there was at least one match
908                 1 otherwise (no matches)                 1 otherwise (no matches)
909                   2 if there is a read error on a .bz2 file
910  */  */
911    
912  static int  static int
913  pcregrep(FILE *in, char *printname)  pcregrep(void *handle, int frtype, char *printname)
914  {  {
915  int rc = 1;  int rc = 1;
916  int linenumber = 1;  int linenumber = 1;
917  int lastmatchnumber = 0;  int lastmatchnumber = 0;
918  int count = 0;  int count = 0;
919  int filepos = 0;  int filepos = 0;
920  int offsets[99];  int offsets[OFFSET_SIZE];
921  char *lastmatchrestart = NULL;  char *lastmatchrestart = NULL;
922  char buffer[3*MBUFTHIRD];  char buffer[3*MBUFTHIRD];
923  char *ptr = buffer;  char *ptr = buffer;
924  char *endptr;  char *endptr;
925  size_t bufflength;  size_t bufflength;
926  BOOL endhyphenpending = FALSE;  BOOL endhyphenpending = FALSE;
927    FILE *in = NULL;                    /* Ensure initialized */
928    
929    #ifdef SUPPORT_LIBZ
930    gzFile ingz = NULL;
931    #endif
932    
933    #ifdef SUPPORT_LIBBZ2
934    BZFILE *inbz2 = NULL;
935    #endif
936    
937    
938  /* Do the first read into the start of the buffer and set up the pointer to  /* Do the first read into the start of the buffer and set up the pointer to end
939  end of what we have. */  of what we have. In the case of libz, a non-zipped .gz file will be read as a
940    plain file. However, if a .bz2 file isn't actually bzipped, the first read will
941    fail. */
942    
943    #ifdef SUPPORT_LIBZ
944    if (frtype == FR_LIBZ)
945      {
946      ingz = (gzFile)handle;
947      bufflength = gzread (ingz, buffer, 3*MBUFTHIRD);
948      }
949    else
950    #endif
951    
952    #ifdef SUPPORT_LIBBZ2
953    if (frtype == FR_LIBBZ2)
954      {
955      inbz2 = (BZFILE *)handle;
956      bufflength = BZ2_bzread(inbz2, buffer, 3*MBUFTHIRD);
957      if ((int)bufflength < 0) return 2;   /* Gotcha: bufflength is size_t; */
958      }                                    /* without the cast it is unsigned. */
959    else
960    #endif
961    
962      {
963      in = (FILE *)handle;
964      bufflength = fread(buffer, 1, 3*MBUFTHIRD, in);
965      }
966    
 bufflength = fread(buffer, 1, 3*MBUFTHIRD, in);  
967  endptr = buffer + bufflength;  endptr = buffer + bufflength;
968    
969  /* 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
# Line 850  way, the buffer is shifted left and re-f Line 973  way, the buffer is shifted left and re-f
973    
974  while (ptr < endptr)  while (ptr < endptr)
975    {    {
976    int i, endlinelength;    int endlinelength;
977    int mrc = 0;    int mrc = 0;
978    BOOL match = FALSE;    BOOL match;
979    char *matchptr = ptr;    char *matchptr = ptr;
980    char *t = ptr;    char *t = ptr;
981    size_t length, linelength;    size_t length, linelength;
982    
983    /* At this point, ptr is at the start of a line. We need to find the length    /* At this point, ptr is at the start of a line. We need to find the length
984    of the subject string to pass to pcre_exec(). In multiline mode, it is the    of the subject string to pass to pcre_exec(). In multiline mode, it is the
985    length remainder of the data in the buffer. Otherwise, it is the length of    length remainder of the data in the buffer. Otherwise, it is the length of
986    the next line. After matching, we always advance by the length of the next    the next line, excluding the terminating newline. After matching, we always
987    line. In multiline mode the PCRE_FIRSTLINE option is used for compiling, so    advance by the length of the next line. In multiline mode the PCRE_FIRSTLINE
988    that any match is constrained to be in the first line. */    option is used for compiling, so that any match is constrained to be in the
989      first line. */
990    
991    t = end_of_line(t, endptr, &endlinelength);    t = end_of_line(t, endptr, &endlinelength);
992    linelength = t - ptr - endlinelength;    linelength = t - ptr - endlinelength;
# Line 877  while (ptr < endptr) Line 1001  while (ptr < endptr)
1001        #include <time.h>        #include <time.h>
1002        struct timeval start_time, end_time;        struct timeval start_time, end_time;
1003        struct timezone dummy;        struct timezone dummy;
1004          int i;
1005    
1006        if (jfriedl_XT)        if (jfriedl_XT)
1007        {        {
# Line 902  while (ptr < endptr) Line 1027  while (ptr < endptr)
1027    
1028    
1029        for (i = 0; i < jfriedl_XR; i++)        for (i = 0; i < jfriedl_XR; i++)
1030            match = (pcre_exec(pattern_list[0], hints_list[0], ptr, length, 0, 0, offsets, 99) >= 0);            match = (pcre_exec(pattern_list[0], hints_list[0], ptr, length, 0,
1031                  PCRE_NOTEMPTY, offsets, OFFSET_SIZE) >= 0);
1032    
1033        if (gettimeofday(&end_time, &dummy) != 0)        if (gettimeofday(&end_time, &dummy) != 0)
1034                perror("bad gettimeofday");                perror("bad gettimeofday");
# Line 916  while (ptr < endptr) Line 1042  while (ptr < endptr)
1042    }    }
1043  #endif  #endif
1044    
1045    /* We come back here after a match when the -o option (only_matching) is set,    /* We come back here after a match when the -o option (only_matching) is set,
1046    in order to find any further matches in the same line. */    in order to find any further matches in the same line. */
   
   ONLY_MATCHING_RESTART:  
1047    
1048    /* Run through all the patterns until one matches. Note that we don't include    ONLY_MATCHING_RESTART:
   the final newline in the subject string. */  
1049    
1050    for (i = 0; i < pattern_count; i++)    /* Run through all the patterns until one matches or there is an error other
1051      {    than NOMATCH. This code is in a subroutine so that it can be re-used for
1052      mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, length, 0, 0,    finding subsequent matches when colouring matched lines. */
1053        offsets, 99);  
1054      if (mrc >= 0) { match = TRUE; break; }    match = match_patterns(matchptr, length, offsets, &mrc);
     if (mrc != PCRE_ERROR_NOMATCH)  
       {  
       fprintf(stderr, "pcregrep: pcre_exec() error %d while matching ", mrc);  
       if (pattern_count > 1) fprintf(stderr, "pattern number %d to ", i+1);  
       fprintf(stderr, "this line:\n");  
       fwrite(matchptr, 1, linelength, stderr);  /* In case binary zero included */  
       fprintf(stderr, "\n");  
       if (error_count == 0 &&  
           (mrc == PCRE_ERROR_MATCHLIMIT || mrc == PCRE_ERROR_RECURSIONLIMIT))  
         {  
         fprintf(stderr, "pcregrep: error %d means that a resource limit "  
           "was exceeded\n", mrc);  
         fprintf(stderr, "pcregrep: check your regex for nested unlimited loops\n");  
         }  
       if (error_count++ > 20)  
         {  
         fprintf(stderr, "pcregrep: too many errors - abandoned\n");  
         exit(2);  
         }  
       match = invert;    /* No more matching; don't show the line again */  
       break;  
       }  
     }  
1055    
1056    /* If it's a match or a not-match (as required), do what's wanted. */    /* If it's a match or a not-match (as required), do what's wanted. */
1057    
# Line 970  while (ptr < endptr) Line 1070  while (ptr < endptr)
1070      /* 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
1071      in the file. */      in the file. */
1072    
1073      else if (filenames == FN_ONLY)      else if (filenames == FN_MATCH_ONLY)
1074        {        {
1075        fprintf(stdout, "%s\n", printname);        fprintf(stdout, "%s\n", printname);
1076        return 0;        return 0;
# Line 981  while (ptr < endptr) Line 1081  while (ptr < endptr)
1081      else if (quiet) return 0;      else if (quiet) return 0;
1082    
1083      /* The --only-matching option prints just the substring that matched, and      /* The --only-matching option prints just the substring that matched, and
1084      the --file-offsets and --line-offsets options output offsets for the      the --file-offsets and --line-offsets options output offsets for the
1085      matching substring (they both force --only-matching). None of these options      matching substring (they both force --only-matching). None of these options
1086      prints any context. Afterwards, adjust the start and length, and then jump      prints any context. Afterwards, adjust the start and length, and then jump
1087      back to look for further matches in the same line. If we are in invert      back to look for further matches in the same line. If we are in invert
# Line 991  while (ptr < endptr) Line 1091  while (ptr < endptr)
1091      else if (only_matching)      else if (only_matching)
1092        {        {
1093        if (!invert)        if (!invert)
1094          {          {
1095          if (printname != NULL) fprintf(stdout, "%s:", printname);          if (printname != NULL) fprintf(stdout, "%s:", printname);
1096          if (number) fprintf(stdout, "%d:", linenumber);          if (number) fprintf(stdout, "%d:", linenumber);
1097          if (line_offsets)          if (line_offsets)
1098            fprintf(stdout, "%d,%d", matchptr + offsets[0] - ptr,            fprintf(stdout, "%d,%d", (int)(matchptr + offsets[0] - ptr),
1099              offsets[1] - offsets[0]);              offsets[1] - offsets[0]);
1100          else if (file_offsets)          else if (file_offsets)
1101            fprintf(stdout, "%d,%d", filepos + matchptr + offsets[0] - ptr,            fprintf(stdout, "%d,%d", (int)(filepos + matchptr + offsets[0] - ptr),
1102              offsets[1] - offsets[0]);              offsets[1] - offsets[0]);
1103          else          else
1104            fwrite(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);            {
1105              if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1106              FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
1107              if (do_colour) fprintf(stdout, "%c[00m", 0x1b);
1108              }
1109          fprintf(stdout, "\n");          fprintf(stdout, "\n");
1110          matchptr += offsets[1];          matchptr += offsets[1];
1111          length -= offsets[1];          length -= offsets[1];
1112          match = FALSE;          match = FALSE;
1113          goto ONLY_MATCHING_RESTART;          goto ONLY_MATCHING_RESTART;
1114          }          }
1115        }        }
1116    
1117      /* This is the default case when none of the above options is set. We print      /* This is the default case when none of the above options is set. We print
# Line 1041  while (ptr < endptr) Line 1145  while (ptr < endptr)
1145            if (printname != NULL) fprintf(stdout, "%s-", printname);            if (printname != NULL) fprintf(stdout, "%s-", printname);
1146            if (number) fprintf(stdout, "%d-", lastmatchnumber++);            if (number) fprintf(stdout, "%d-", lastmatchnumber++);
1147            pp = end_of_line(pp, endptr, &ellength);            pp = end_of_line(pp, endptr, &ellength);
1148            fwrite(lastmatchrestart, 1, pp - lastmatchrestart, stdout);            FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
1149            lastmatchrestart = pp;            lastmatchrestart = pp;
1150            }            }
1151          if (lastmatchrestart != ptr) hyphenpending = TRUE;          if (lastmatchrestart != ptr) hyphenpending = TRUE;
# Line 1081  while (ptr < endptr) Line 1185  while (ptr < endptr)
1185            if (printname != NULL) fprintf(stdout, "%s-", printname);            if (printname != NULL) fprintf(stdout, "%s-", printname);
1186            if (number) fprintf(stdout, "%d-", linenumber - linecount--);            if (number) fprintf(stdout, "%d-", linenumber - linecount--);
1187            pp = end_of_line(pp, endptr, &ellength);            pp = end_of_line(pp, endptr, &ellength);
1188            fwrite(p, 1, pp - p, stdout);            FWRITE(p, 1, pp - p, stdout);
1189            p = pp;            p = pp;
1190            }            }
1191          }          }
# Line 1131  while (ptr < endptr) Line 1235  while (ptr < endptr)
1235          {          {
1236          int first = S_arg * 2;          int first = S_arg * 2;
1237          int last  = first + 1;          int last  = first + 1;
1238          fwrite(ptr, 1, offsets[first], stdout);          FWRITE(ptr, 1, offsets[first], stdout);
1239          fprintf(stdout, "X");          fprintf(stdout, "X");
1240          fwrite(ptr + offsets[last], 1, linelength - offsets[last], stdout);          FWRITE(ptr + offsets[last], 1, linelength - offsets[last], stdout);
1241          }          }
1242        else        else
1243  #endif  #endif
1244    
1245        /* We have to split the line(s) up if colouring. */        /* We have to split the line(s) up if colouring, and search for further
1246          matches. */
1247    
1248        if (do_colour)        if (do_colour)
1249          {          {
1250          fwrite(ptr, 1, offsets[0], stdout);          int last_offset = 0;
1251            FWRITE(ptr, 1, offsets[0], stdout);
1252          fprintf(stdout, "%c[%sm", 0x1b, colour_string);          fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1253          fwrite(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);          FWRITE(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
1254          fprintf(stdout, "%c[00m", 0x1b);          fprintf(stdout, "%c[00m", 0x1b);
1255          fwrite(ptr + offsets[1], 1, (linelength + endlinelength) - offsets[1],          for (;;)
1256            stdout);            {
1257              last_offset += offsets[1];
1258              matchptr += offsets[1];
1259              length -= offsets[1];
1260              if (!match_patterns(matchptr, length, offsets, &mrc)) break;
1261              FWRITE(matchptr, 1, offsets[0], stdout);
1262              fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1263              FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
1264              fprintf(stdout, "%c[00m", 0x1b);
1265              }
1266            FWRITE(ptr + last_offset, 1,
1267              (linelength + endlinelength) - last_offset, stdout);
1268          }          }
1269        else fwrite(ptr, 1, linelength + endlinelength, stdout);  
1270          /* Not colouring; no need to search for further matches */
1271    
1272          else FWRITE(ptr, 1, linelength + endlinelength, stdout);
1273        }        }
1274    
1275      /* End of doing what has to be done for a match */      /* End of doing what has to be done for a match */
# Line 1181  while (ptr < endptr) Line 1301  while (ptr < endptr)
1301      linelength = endmatch - ptr - ellength;      linelength = endmatch - ptr - ellength;
1302      }      }
1303    
1304    /* Advance to after the newline and increment the line number. The file    /* Advance to after the newline and increment the line number. The file
1305    offset to the current line is maintained in filepos. */    offset to the current line is maintained in filepos. */
1306    
1307    ptr += linelength + endlinelength;    ptr += linelength + endlinelength;
# Line 1207  while (ptr < endptr) Line 1327  while (ptr < endptr)
1327    
1328      memmove(buffer, buffer + MBUFTHIRD, 2*MBUFTHIRD);      memmove(buffer, buffer + MBUFTHIRD, 2*MBUFTHIRD);
1329      ptr -= MBUFTHIRD;      ptr -= MBUFTHIRD;
1330    
1331    #ifdef SUPPORT_LIBZ
1332        if (frtype == FR_LIBZ)
1333          bufflength = 2*MBUFTHIRD +
1334            gzread (ingz, buffer + 2*MBUFTHIRD, MBUFTHIRD);
1335        else
1336    #endif
1337    
1338    #ifdef SUPPORT_LIBBZ2
1339        if (frtype == FR_LIBBZ2)
1340          bufflength = 2*MBUFTHIRD +
1341            BZ2_bzread(inbz2, buffer + 2*MBUFTHIRD, MBUFTHIRD);
1342        else
1343    #endif
1344    
1345      bufflength = 2*MBUFTHIRD + fread(buffer + 2*MBUFTHIRD, 1, MBUFTHIRD, in);      bufflength = 2*MBUFTHIRD + fread(buffer + 2*MBUFTHIRD, 1, MBUFTHIRD, in);
1346    
1347      endptr = buffer + bufflength;      endptr = buffer + bufflength;
1348    
1349      /* Adjust any last match point */      /* Adjust any last match point */
# Line 1238  if (filenames == FN_NOMATCH_ONLY) Line 1374  if (filenames == FN_NOMATCH_ONLY)
1374    
1375  if (count_only)  if (count_only)
1376    {    {
1377    if (printname != NULL) fprintf(stdout, "%s:", printname);    if (count > 0 || !omit_zero_count)
1378    fprintf(stdout, "%d\n", count);      {
1379        if (printname != NULL && filenames != FN_NONE)
1380          fprintf(stdout, "%s:", printname);
1381        fprintf(stdout, "%d\n", count);
1382        }
1383    }    }
1384    
1385  return rc;  return rc;
# Line 1271  grep_or_recurse(char *pathname, BOOL dir Line 1411  grep_or_recurse(char *pathname, BOOL dir
1411  {  {
1412  int rc = 1;  int rc = 1;
1413  int sep;  int sep;
1414  FILE *in;  int frtype;
1415    int pathlen;
1416    void *handle;
1417    FILE *in = NULL;           /* Ensure initialized */
1418    
1419    #ifdef SUPPORT_LIBZ
1420    gzFile ingz = NULL;
1421    #endif
1422    
1423    #ifdef SUPPORT_LIBBZ2
1424    BZFILE *inbz2 = NULL;
1425    #endif
1426    
1427  /* If the file name is "-" we scan stdin */  /* If the file name is "-" we scan stdin */
1428    
1429  if (strcmp(pathname, "-") == 0)  if (strcmp(pathname, "-") == 0)
1430    {    {
1431    return pcregrep(stdin,    return pcregrep(stdin, FR_PLAIN,
1432      (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))?      (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))?
1433        stdin_name : NULL);        stdin_name : NULL);
1434    }    }
1435    
   
1436  /* If the file is a directory, skip if skipping or if we are recursing, scan  /* If the file is a directory, skip if skipping or if we are recursing, scan
1437  each file within it, subject to any include or exclude patterns that were set.  each file and directory within it, subject to any include or exclude patterns
1438  The scanning code is localized so it can be made system-specific. */  that were set. The scanning code is localized so it can be made
1439    system-specific. */
1440    
1441  if ((sep = isdirectory(pathname)) != 0)  if ((sep = isdirectory(pathname)) != 0)
1442    {    {
# Line 1306  if ((sep = isdirectory(pathname)) != 0) Line 1457  if ((sep = isdirectory(pathname)) != 0)
1457    
1458      while ((nextfile = readdirectory(dir)) != NULL)      while ((nextfile = readdirectory(dir)) != NULL)
1459        {        {
1460        int frc, blen;        int frc, nflen;
1461        sprintf(buffer, "%.512s%c%.128s", pathname, sep, nextfile);        sprintf(buffer, "%.512s%c%.128s", pathname, sep, nextfile);
1462        blen = strlen(buffer);        nflen = strlen(nextfile);
1463    
1464        if (exclude_compiled != NULL &&        if (isdirectory(buffer))
1465            pcre_exec(exclude_compiled, NULL, buffer, blen, 0, 0, NULL, 0) >= 0)          {
1466          continue;          if (exclude_dir_compiled != NULL &&
1467                pcre_exec(exclude_dir_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) >= 0)
1468        if (include_compiled != NULL &&            continue;
1469            pcre_exec(include_compiled, NULL, buffer, blen, 0, 0, NULL, 0) < 0)  
1470          continue;          if (include_dir_compiled != NULL &&
1471                pcre_exec(include_dir_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) < 0)
1472              continue;
1473            }
1474          else
1475            {
1476            if (exclude_compiled != NULL &&
1477                pcre_exec(exclude_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) >= 0)
1478              continue;
1479    
1480            if (include_compiled != NULL &&
1481                pcre_exec(include_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) < 0)
1482              continue;
1483            }
1484    
1485        frc = grep_or_recurse(buffer, dir_recurse, FALSE);        frc = grep_or_recurse(buffer, dir_recurse, FALSE);
1486        if (frc > 1) rc = frc;        if (frc > 1) rc = frc;
# Line 1339  skipping was not requested. The scan pro Line 1503  skipping was not requested. The scan pro
1503  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
1504  the file name, or the filename was forced (-H). */  the file name, or the filename was forced (-H). */
1505    
1506  in = fopen(pathname, "r");  pathlen = strlen(pathname);
1507  if (in == NULL)  
1508    /* Open using zlib if it is supported and the file name ends with .gz. */
1509    
1510    #ifdef SUPPORT_LIBZ
1511    if (pathlen > 3 && strcmp(pathname + pathlen - 3, ".gz") == 0)
1512      {
1513      ingz = gzopen(pathname, "rb");
1514      if (ingz == NULL)
1515        {
1516        if (!silent)
1517          fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname,
1518            strerror(errno));
1519        return 2;
1520        }
1521      handle = (void *)ingz;
1522      frtype = FR_LIBZ;
1523      }
1524    else
1525    #endif
1526    
1527    /* Otherwise open with bz2lib if it is supported and the name ends with .bz2. */
1528    
1529    #ifdef SUPPORT_LIBBZ2
1530    if (pathlen > 4 && strcmp(pathname + pathlen - 4, ".bz2") == 0)
1531      {
1532      inbz2 = BZ2_bzopen(pathname, "rb");
1533      handle = (void *)inbz2;
1534      frtype = FR_LIBBZ2;
1535      }
1536    else
1537    #endif
1538    
1539    /* Otherwise use plain fopen(). The label is so that we can come back here if
1540    an attempt to read a .bz2 file indicates that it really is a plain file. */
1541    
1542    #ifdef SUPPORT_LIBBZ2
1543    PLAIN_FILE:
1544    #endif
1545      {
1546      in = fopen(pathname, "rb");
1547      handle = (void *)in;
1548      frtype = FR_PLAIN;
1549      }
1550    
1551    /* All the opening methods return errno when they fail. */
1552    
1553    if (handle == NULL)
1554    {    {
1555    if (!silent)    if (!silent)
1556      fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname,      fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname,
# Line 1348  if (in == NULL) Line 1558  if (in == NULL)
1558    return 2;    return 2;
1559    }    }
1560    
1561  rc = pcregrep(in, (filenames > FN_DEFAULT ||  /* Now grep the file */
1562    
1563    rc = pcregrep(handle, frtype, (filenames > FN_DEFAULT ||
1564    (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL);    (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL);
1565    
1566    /* Close in an appropriate manner. */
1567    
1568    #ifdef SUPPORT_LIBZ
1569    if (frtype == FR_LIBZ)
1570      gzclose(ingz);
1571    else
1572    #endif
1573    
1574    /* If it is a .bz2 file and the result is 2, it means that the first attempt to
1575    read failed. If the error indicates that the file isn't in fact bzipped, try
1576    again as a normal file. */
1577    
1578    #ifdef SUPPORT_LIBBZ2
1579    if (frtype == FR_LIBBZ2)
1580      {
1581      if (rc == 2)
1582        {
1583        int errnum;
1584        const char *err = BZ2_bzerror(inbz2, &errnum);
1585        if (errnum == BZ_DATA_ERROR_MAGIC)
1586          {
1587          BZ2_bzclose(inbz2);
1588          goto PLAIN_FILE;
1589          }
1590        else if (!silent)
1591          fprintf(stderr, "pcregrep: Failed to read %s using bzlib: %s\n",
1592            pathname, err);
1593        }
1594      BZ2_bzclose(inbz2);
1595      }
1596    else
1597    #endif
1598    
1599    /* Normal file close */
1600    
1601  fclose(in);  fclose(in);
1602    
1603    /* Pass back the yield from pcregrep(). */
1604    
1605  return rc;  return rc;
1606  }  }
1607    
# Line 1392  option_item *op; Line 1642  option_item *op;
1642  printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n");  printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n");
1643  printf("Search for PATTERN in each FILE or standard input.\n");  printf("Search for PATTERN in each FILE or standard input.\n");
1644  printf("PATTERN must be present if neither -e nor -f is used.\n");  printf("PATTERN must be present if neither -e nor -f is used.\n");
1645  printf("\"-\" can be used as a file name to mean STDIN.\n\n");  printf("\"-\" can be used as a file name to mean STDIN.\n");
1646  printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n");  
1647    #ifdef SUPPORT_LIBZ
1648    printf("Files whose names end in .gz are read using zlib.\n");
1649    #endif
1650    
1651    #ifdef SUPPORT_LIBBZ2
1652    printf("Files whose names end in .bz2 are read using bzlib2.\n");
1653    #endif
1654    
1655    #if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2
1656    printf("Other files and the standard input are read as plain files.\n\n");
1657    #else
1658    printf("All files are read as plain files, without any interpretation.\n\n");
1659    #endif
1660    
1661    printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n");
1662  printf("Options:\n");  printf("Options:\n");
1663    
1664  for (op = optionlist; op->one_char != 0; op++)  for (op = optionlist; op->one_char != 0; op++)
# Line 1402  for (op = optionlist; op->one_char != 0; Line 1666  for (op = optionlist; op->one_char != 0;
1666    int n;    int n;
1667    char s[4];    char s[4];
1668    if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, "   ");    if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, "   ");
1669    printf("  %s --%s%n", s, op->long_name, &n);    n = 30 - printf("  %s --%s", s, op->long_name);
   n = 30 - n;  
1670    if (n < 1) n = 1;    if (n < 1) n = 1;
1671    printf("%.*s%s\n", n, "                    ", op->help_text);    printf("%.*s%s\n", n, "                    ", op->help_text);
1672    }    }
# Line 1428  handle_option(int letter, int options) Line 1691  handle_option(int letter, int options)
1691  {  {
1692  switch(letter)  switch(letter)
1693    {    {
1694    case N_FOFFSETS: file_offsets = TRUE; break;    case N_FOFFSETS: file_offsets = TRUE; break;
1695    case N_HELP: help(); exit(0);    case N_HELP: help(); exit(0);
1696    case N_LOFFSETS: line_offsets = number = TRUE; break;    case N_LOFFSETS: line_offsets = number = TRUE; break;
1697    case 'c': count_only = TRUE; break;    case 'c': count_only = TRUE; break;
1698    case 'F': process_options |= PO_FIXED_STRINGS; break;    case 'F': process_options |= PO_FIXED_STRINGS; break;
1699    case 'H': filenames = FN_FORCE; break;    case 'H': filenames = FN_FORCE; break;
1700    case 'h': filenames = FN_NONE; break;    case 'h': filenames = FN_NONE; break;
1701    case 'i': options |= PCRE_CASELESS; break;    case 'i': options |= PCRE_CASELESS; break;
1702    case 'l': filenames = FN_ONLY; break;    case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break;
1703    case 'L': filenames = FN_NOMATCH_ONLY; break;    case 'L': filenames = FN_NOMATCH_ONLY; break;
1704    case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break;    case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break;
1705    case 'n': number = TRUE; break;    case 'n': number = TRUE; break;
# Line 1621  const char *error; Line 1884  const char *error;
1884    
1885  /* Set the default line ending value from the default in the PCRE library;  /* Set the default line ending value from the default in the PCRE library;
1886  "lf", "cr", "crlf", and "any" are supported. Anything else is treated as "lf".  "lf", "cr", "crlf", and "any" are supported. Anything else is treated as "lf".
1887  */  Note that the return values from pcre_config(), though derived from the ASCII
1888    codes, are the same in EBCDIC environments, so we must use the actual values
1889    rather than escapes such as as '\r'. */
1890    
1891  (void)pcre_config(PCRE_CONFIG_NEWLINE, &i);  (void)pcre_config(PCRE_CONFIG_NEWLINE, &i);
1892  switch(i)  switch(i)
1893    {    {
1894    default:                 newline = (char *)"lf"; break;    default:               newline = (char *)"lf"; break;
1895    case '\r':               newline = (char *)"cr"; break;    case 13:               newline = (char *)"cr"; break;
1896    case ('\r' << 8) | '\n': newline = (char *)"crlf"; break;    case (13 << 8) | 10:   newline = (char *)"crlf"; break;
1897    case -1:                 newline = (char *)"any"; break;    case -1:               newline = (char *)"any"; break;
1898    case -2:                 newline = (char *)"anycrlf"; break;    case -2:               newline = (char *)"anycrlf"; break;
1899    }    }
1900    
1901  /* Process the options */  /* Process the options */
# Line 1672  for (i = 1; i < argc; i++) Line 1937  for (i = 1; i < argc; i++)
1937      Some options have variations in the long name spelling: specifically, we      Some options have variations in the long name spelling: specifically, we
1938      allow "regexp" because GNU grep allows it, though I personally go along      allow "regexp" because GNU grep allows it, though I personally go along
1939      with Jeffrey Friedl and Larry Wall in preferring "regex" without the "p".      with Jeffrey Friedl and Larry Wall in preferring "regex" without the "p".
1940      These options are entered in the table as "regex(p)". No option is in both      These options are entered in the table as "regex(p)". Options can be in
1941      these categories, fortunately. */      both these categories. */
1942    
1943      for (op = optionlist; op->one_char != 0; op++)      for (op = optionlist; op->one_char != 0; op++)
1944        {        {
1945        char *opbra = strchr(op->long_name, '(');        char *opbra = strchr(op->long_name, '(');
1946        char *equals = strchr(op->long_name, '=');        char *equals = strchr(op->long_name, '=');
1947        if (opbra == NULL)     /* Not a (p) case */  
1948          /* Handle options with only one spelling of the name */
1949    
1950          if (opbra == NULL)     /* Does not contain '(' */
1951          {          {
1952          if (equals == NULL)  /* Not thing=data case */          if (equals == NULL)  /* Not thing=data case */
1953            {            {
# Line 1701  for (i = 1; i < argc; i++) Line 1969  for (i = 1; i < argc; i++)
1969              }              }
1970            }            }
1971          }          }
1972        else                   /* Special case xxxx(p) */  
1973          /* Handle options with an alternate spelling of the name */
1974    
1975          else
1976          {          {
1977          char buff1[24];          char buff1[24];
1978          char buff2[24];          char buff2[24];
1979    
1980          int baselen = opbra - op->long_name;          int baselen = opbra - op->long_name;
1981            int fulllen = strchr(op->long_name, ')') - op->long_name + 1;
1982            int arglen = (argequals == NULL || equals == NULL)?
1983              (int)strlen(arg) : argequals - arg;
1984    
1985          sprintf(buff1, "%.*s", baselen, op->long_name);          sprintf(buff1, "%.*s", baselen, op->long_name);
1986          sprintf(buff2, "%s%.*s", buff1,          sprintf(buff2, "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1);
1987            (int)strlen(op->long_name) - baselen - 2, opbra + 1);  
1988          if (strcmp(arg, buff1) == 0 || strcmp(arg, buff2) == 0)          if (strncmp(arg, buff1, arglen) == 0 ||
1989               strncmp(arg, buff2, arglen) == 0)
1990              {
1991              if (equals != NULL && argequals != NULL)
1992                {
1993                option_data = argequals;
1994                if (*option_data == '=')
1995                  {
1996                  option_data++;
1997                  longopwasequals = TRUE;
1998                  }
1999                }
2000            break;            break;
2001              }
2002          }          }
2003        }        }
2004    
# Line 1721  for (i = 1; i < argc; i++) Line 2009  for (i = 1; i < argc; i++)
2009        }        }
2010      }      }
2011    
   
2012    /* Jeffrey Friedl's debugging harness uses these additional options which    /* Jeffrey Friedl's debugging harness uses these additional options which
2013    are not in the right form for putting in the option table because they use    are not in the right form for putting in the option table because they use
2014    only one hyphen, yet are more than one character long. By putting them    only one hyphen, yet are more than one character long. By putting them
# Line 1866  if (both_context > 0) Line 2153  if (both_context > 0)
2153    if (after_context == 0) after_context = both_context;    if (after_context == 0) after_context = both_context;
2154    if (before_context == 0) before_context = both_context;    if (before_context == 0) before_context = both_context;
2155    }    }
2156    
2157  /* Only one of --only-matching, --file-offsets, or --line-offsets is permitted.  /* Only one of --only-matching, --file-offsets, or --line-offsets is permitted.
2158  However, the latter two set the only_matching flag. */  However, the latter two set the only_matching flag. */
2159    
2160  if ((only_matching && (file_offsets || line_offsets)) ||  if ((only_matching && (file_offsets || line_offsets)) ||
2161      (file_offsets && line_offsets))      (file_offsets && line_offsets))
2162    {    {
2163    fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets "    fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets "
2164      "and/or --line-offsets\n");      "and/or --line-offsets\n");
2165    exit(usage(2));    exit(usage(2));
2166    }    }
2167    
2168  if (file_offsets || line_offsets) only_matching = TRUE;  if (file_offsets || line_offsets) only_matching = TRUE;
2169    
2170  /* If a locale has not been provided as an option, see if the LC_CTYPE or  /* If a locale has not been provided as an option, see if the LC_CTYPE or
2171  LC_ALL environment variable is set, and if so, use it. */  LC_ALL environment variable is set, and if so, use it. */
# Line 2113  if (include_pattern != NULL) Line 2400  if (include_pattern != NULL)
2400      }      }
2401    }    }
2402    
2403    if (exclude_dir_pattern != NULL)
2404      {
2405      exclude_dir_compiled = pcre_compile(exclude_dir_pattern, 0, &error, &errptr,
2406        pcretables);
2407      if (exclude_dir_compiled == NULL)
2408        {
2409        fprintf(stderr, "pcregrep: Error in 'exclude_dir' regex at offset %d: %s\n",
2410          errptr, error);
2411        goto EXIT2;
2412        }
2413      }
2414    
2415    if (include_dir_pattern != NULL)
2416      {
2417      include_dir_compiled = pcre_compile(include_dir_pattern, 0, &error, &errptr,
2418        pcretables);
2419      if (include_dir_compiled == NULL)
2420        {
2421        fprintf(stderr, "pcregrep: Error in 'include_dir' regex at offset %d: %s\n",
2422          errptr, error);
2423        goto EXIT2;
2424        }
2425      }
2426    
2427  /* If there are no further arguments, do the business on stdin and exit. */  /* If there are no further arguments, do the business on stdin and exit. */
2428    
2429  if (i >= argc)  if (i >= argc)
2430    {    {
2431    rc = pcregrep(stdin, (filenames > FN_DEFAULT)? stdin_name : NULL);    rc = pcregrep(stdin, FR_PLAIN, (filenames > FN_DEFAULT)? stdin_name : NULL);
2432    goto EXIT;    goto EXIT;
2433    }    }
2434    

Legend:
Removed from v.283  
changed lines
  Added in v.515

  ViewVC Help
Powered by ViewVC 1.1.5