/[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 1033 by ph10, Mon Sep 10 11:02:48 2012 UTC revision 1355 by ph10, Tue Aug 13 17:34:02 2013 UTC
# Line 3  Line 3 
3  *************************************************/  *************************************************/
4    
5  /* This is a grep program that uses the PCRE regular expression library to do  /* This is a grep program that uses the PCRE regular expression library to do
6  its pattern matching. On a Unix or Win32 system it can recurse into  its pattern matching. On Unix-like, Windows, and native z/OS systems it can
7  directories.  recurse into directories, and in z/OS it can handle PDS files.
8    
9             Copyright (c) 1997-2012 University of Cambridge  Note that for native z/OS, in addition to defining the NATIVE_ZOS macro, an
10    additional header is required. That header is not included in the main PCRE
11    distribution because other apparatus is needed to compile pcregrep for z/OS.
12    The header can be found in the special z/OS distribution, which is available
13    from www.zaconsultants.net or from www.cbttape.org.
14    
15               Copyright (c) 1997-2013 University of Cambridge
16    
17  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
18  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 143  static char *DEE_option = NULL; Line 149  static char *DEE_option = NULL;
149  static char *locale = NULL;  static char *locale = NULL;
150  static char *main_buffer = NULL;  static char *main_buffer = NULL;
151  static char *newline = NULL;  static char *newline = NULL;
152    static char *om_separator = (char *)"";
153  static char *stdin_name = (char *)"(standard input)";  static char *stdin_name = (char *)"(standard input)";
154    
155  static const unsigned char *pcretables = NULL;  static const unsigned char *pcretables = NULL;
# Line 163  static int dee_action = dee_READ; Line 170  static int dee_action = dee_READ;
170  static int DEE_action = DEE_READ;  static int DEE_action = DEE_READ;
171  static int error_count = 0;  static int error_count = 0;
172  static int filenames = FN_DEFAULT;  static int filenames = FN_DEFAULT;
 static int only_matching = -1;  
173  static int pcre_options = 0;  static int pcre_options = 0;
174  static int process_options = 0;  static int process_options = 0;
175    
# Line 188  static BOOL number = FALSE; Line 194  static BOOL number = FALSE;
194  static BOOL omit_zero_count = FALSE;  static BOOL omit_zero_count = FALSE;
195  static BOOL resource_error = FALSE;  static BOOL resource_error = FALSE;
196  static BOOL quiet = FALSE;  static BOOL quiet = FALSE;
197    static BOOL show_only_matching = FALSE;
198  static BOOL silent = FALSE;  static BOOL silent = FALSE;
199  static BOOL utf8 = FALSE;  static BOOL utf8 = FALSE;
200    
201    /* Structure for list of --only-matching capturing numbers. */
202    
203    typedef struct omstr {
204      struct omstr *next;
205      int groupnum;
206    } omstr;
207    
208    static omstr *only_matching = NULL;
209    static omstr *only_matching_last = NULL;
210    
211    /* Structure for holding the two variables that describe a number chain. */
212    
213    typedef struct omdatastr {
214      omstr **anchor;
215      omstr **lastptr;
216    } omdatastr;
217    
218    static omdatastr only_matching_data = { &only_matching, &only_matching_last };
219    
220  /* Structure for list of file names (for -f and --{in,ex}clude-from) */  /* Structure for list of file names (for -f and --{in,ex}clude-from) */
221    
222  typedef struct fnstr {  typedef struct fnstr {
# Line 264  static const char *incexname[4] = { "--i Line 290  static const char *incexname[4] = { "--i
290  /* Structure for options and list of them */  /* Structure for options and list of them */
291    
292  enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_LONGNUMBER,  enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_LONGNUMBER,
293         OP_OP_NUMBER, OP_PATLIST, OP_FILELIST, OP_BINFILES };         OP_OP_NUMBER, OP_OP_NUMBERS, OP_PATLIST, OP_FILELIST, OP_BINFILES };
294    
295  typedef struct option_item {  typedef struct option_item {
296    int type;    int type;
# Line 297  used to identify them. */ Line 323  used to identify them. */
323  #define N_BINARY_FILES (-18)  #define N_BINARY_FILES (-18)
324  #define N_EXCLUDE_FROM (-19)  #define N_EXCLUDE_FROM (-19)
325  #define N_INCLUDE_FROM (-20)  #define N_INCLUDE_FROM (-20)
326    #define N_OM_SEPARATOR (-21)
327    
328  static option_item optionlist[] = {  static option_item optionlist[] = {
329    { OP_NODATA,     N_NULL,   NULL,              "",              "terminate options" },    { OP_NODATA,     N_NULL,   NULL,              "",              "terminate options" },
# Line 337  static option_item optionlist[] = { Line 364  static option_item optionlist[] = {
364    { OP_NODATA,     'M',      NULL,              "multiline",     "run in multiline mode" },    { OP_NODATA,     'M',      NULL,              "multiline",     "run in multiline mode" },
365    { OP_STRING,     'N',      &newline,          "newline=type",  "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" },    { OP_STRING,     'N',      &newline,          "newline=type",  "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" },
366    { OP_NODATA,     'n',      NULL,              "line-number",   "print line number with output lines" },    { OP_NODATA,     'n',      NULL,              "line-number",   "print line number with output lines" },
367    { OP_OP_NUMBER,  'o',      &only_matching,    "only-matching=n", "show only the part of the line that matched" },    { OP_OP_NUMBERS, 'o',      &only_matching_data, "only-matching=n", "show only the part of the line that matched" },
368      { OP_STRING,     N_OM_SEPARATOR, &om_separator, "om-separator=text", "set separator for multiple -o output" },
369    { OP_NODATA,     'q',      NULL,              "quiet",         "suppress output, just set return code" },    { OP_NODATA,     'q',      NULL,              "quiet",         "suppress output, just set return code" },
370    { OP_NODATA,     'r',      NULL,              "recursive",     "recursively scan sub-directories" },    { OP_NODATA,     'r',      NULL,              "recursive",     "recursively scan sub-directories" },
371    { OP_PATLIST,    N_EXCLUDE,&exclude_patdata,  "exclude=pattern","exclude matching files when recursing" },    { OP_PATLIST,    N_EXCLUDE,&exclude_patdata,  "exclude=pattern","exclude matching files when recursing" },
# Line 393  const char utf8_table4[] = { Line 421  const char utf8_table4[] = {
421    
422    
423  /*************************************************  /*************************************************
424    *         Exit from the program                  *
425    *************************************************/
426    
427    /* If there has been a resource error, give a suitable message.
428    
429    Argument:  the return code
430    Returns:   does not return
431    */
432    
433    static void
434    pcregrep_exit(int rc)
435    {
436    if (resource_error)
437      {
438      fprintf(stderr, "pcregrep: Error %d, %d or %d means that a resource limit "
439        "was exceeded.\n", PCRE_ERROR_MATCHLIMIT, PCRE_ERROR_RECURSIONLIMIT,
440        PCRE_ERROR_JIT_STACKLIMIT);
441      fprintf(stderr, "pcregrep: Check your regex for nested unlimited loops.\n");
442      }
443    exit(rc);
444    }
445    
446    
447    /*************************************************
448  *          Add item to chain of patterns         *  *          Add item to chain of patterns         *
449  *************************************************/  *************************************************/
450    
# Line 403  Arguments: Line 455  Arguments:
455    s          pattern string to add    s          pattern string to add
456    after      if not NULL points to item to insert after    after      if not NULL points to item to insert after
457    
458  Returns:     new pattern block, or NULL after malloc failure  Returns:     new pattern block
459  */  */
460    
461  static patstr *  static patstr *
# Line 413  patstr *p = (patstr *)malloc(sizeof(pats Line 465  patstr *p = (patstr *)malloc(sizeof(pats
465  if (p == NULL)  if (p == NULL)
466    {    {
467    fprintf(stderr, "pcregrep: malloc failed\n");    fprintf(stderr, "pcregrep: malloc failed\n");
468    return NULL;    pcregrep_exit(2);
469    }    }
470  if (strlen(s) > MAXPATLEN)  if (strlen(s) > MAXPATLEN)
471    {    {
# Line 481  while (fn != NULL) Line 533  while (fn != NULL)
533    
534    
535  /*************************************************  /*************************************************
 *         Exit from the program                  *  
 *************************************************/  
   
 /* If there has been a resource error, give a suitable message.  
   
 Argument:  the return code  
 Returns:   does not return  
 */  
   
 static void  
 pcregrep_exit(int rc)  
 {  
 if (resource_error)  
   {  
   fprintf(stderr, "pcregrep: Error %d, %d or %d means that a resource limit "  
     "was exceeded.\n", PCRE_ERROR_MATCHLIMIT, PCRE_ERROR_RECURSIONLIMIT,  
     PCRE_ERROR_JIT_STACKLIMIT);  
   fprintf(stderr, "pcregrep: Check your regex for nested unlimited loops.\n");  
   }  
   
 exit(rc);  
 }  
   
   
 /*************************************************  
536  *            OS-specific functions               *  *            OS-specific functions               *
537  *************************************************/  *************************************************/
538    
539  /* These functions are defined so that they can be made system specific,  /* These functions are defined so that they can be made system specific.
540  although at present the only ones are for Unix, Win32, and for "no support". */  At present there are versions for Unix-style environments, Windows, native
541    z/OS, and "no support". */
542    
543    
544  /************* Directory scanning in Unix ***********/  /************* Directory scanning Unix-style and z/OS ***********/
545    
546  #if defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H  #if (defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H) || defined NATIVE_ZOS
547  #include <sys/types.h>  #include <sys/types.h>
548  #include <sys/stat.h>  #include <sys/stat.h>
549  #include <dirent.h>  #include <dirent.h>
550    
551    #if defined NATIVE_ZOS
552    /************* Directory and PDS/E scanning for z/OS ***********/
553    /************* z/OS looks mostly like Unix with USS ************/
554    /* However, z/OS needs the #include statements in this header */
555    #include "pcrzosfs.h"
556    /* That header is not included in the main PCRE distribution because
557       other apparatus is needed to compile pcregrep for z/OS. The header
558       can be found in the special z/OS distribution, which is available
559       from www.zaconsultants.net or from www.cbttape.org. */
560    #endif
561    
562  typedef DIR directory_type;  typedef DIR directory_type;
563  #define FILESEP '/'  #define FILESEP '/'
564    
# Line 558  closedir(dir); Line 597  closedir(dir);
597  }  }
598    
599    
600  /************* Test for regular file in Unix **********/  /************* Test for regular file, Unix-style **********/
601    
602  static int  static int
603  isregfile(char *filename)  isregfile(char *filename)
# Line 570  return (statbuf.st_mode & S_IFMT) == S_I Line 609  return (statbuf.st_mode & S_IFMT) == S_I
609  }  }
610    
611    
612  /************* Test for a terminal in Unix **********/  #if defined NATIVE_ZOS
613    /************* Test for a terminal in z/OS **********/
614    /* isatty() does not work in a TSO environment, so always give FALSE.*/
615    
616    static BOOL
617    is_stdout_tty(void)
618    {
619    return FALSE;
620    }
621    
622    static BOOL
623    is_file_tty(FILE *f)
624    {
625    return FALSE;
626    }
627    
628    
629    /************* Test for a terminal, Unix-style **********/
630    
631    #else
632  static BOOL  static BOOL
633  is_stdout_tty(void)  is_stdout_tty(void)
634  {  {
# Line 583  is_file_tty(FILE *f) Line 640  is_file_tty(FILE *f)
640  {  {
641  return isatty(fileno(f));  return isatty(fileno(f));
642  }  }
643    #endif
644    
645    /* End of Unix-style or native z/OS environment functions. */
646    
647  /************* Directory scanning in Win32 ***********/  
648    /************* Directory scanning in Windows ***********/
649    
650  /* 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
651  Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES  Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES
# Line 688  free(dir); Line 748  free(dir);
748  }  }
749    
750    
751  /************* Test for regular file in Win32 **********/  /************* Test for regular file in Windows **********/
752    
753  /* I don't know how to do this, or if it can be done; assume all paths are  /* I don't know how to do this, or if it can be done; assume all paths are
754  regular if they are not directories. */  regular if they are not directories. */
# Line 699  return !isdirectory(filename); Line 759  return !isdirectory(filename);
759  }  }
760    
761    
762  /************* Test for a terminal in Win32 **********/  /************* Test for a terminal in Windows **********/
763    
764  /* I don't know how to do this; assume never */  /* I don't know how to do this; assume never */
765    
# Line 715  is_file_tty(FILE *f) Line 775  is_file_tty(FILE *f)
775  return FALSE;  return FALSE;
776  }  }
777    
778    /* End of Windows functions */
779    
780    
781  /************* Directory scanning when we can't do it ***********/  /************* Directory scanning when we can't do it ***********/
782    
# Line 731  char *readdirectory(directory_type *dir) Line 793  char *readdirectory(directory_type *dir)
793  void closedirectory(directory_type *dir) {}  void closedirectory(directory_type *dir) {}
794    
795    
796  /************* Test for regular when we can't do it **********/  /************* Test for regular file when we can't do it **********/
797    
798  /* Assume all files are regular. */  /* Assume all files are regular. */
799    
# Line 752  is_file_tty(FILE *f) Line 814  is_file_tty(FILE *f)
814  return FALSE;  return FALSE;
815  }  }
816    
817  #endif  #endif  /* End of system-specific functions */
818    
819    
820    
# Line 779  return sys_errlist[n]; Line 841  return sys_errlist[n];
841    
842    
843  /*************************************************  /*************************************************
844    *                Usage function                  *
845    *************************************************/
846    
847    static int
848    usage(int rc)
849    {
850    option_item *op;
851    fprintf(stderr, "Usage: pcregrep [-");
852    for (op = optionlist; op->one_char != 0; op++)
853      {
854      if (op->one_char > 0) fprintf(stderr, "%c", op->one_char);
855      }
856    fprintf(stderr, "] [long options] [pattern] [files]\n");
857    fprintf(stderr, "Type `pcregrep --help' for more information and the long "
858      "options.\n");
859    return rc;
860    }
861    
862    
863    
864    /*************************************************
865    *                Help function                   *
866    *************************************************/
867    
868    static void
869    help(void)
870    {
871    option_item *op;
872    
873    printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n");
874    printf("Search for PATTERN in each FILE or standard input.\n");
875    printf("PATTERN must be present if neither -e nor -f is used.\n");
876    printf("\"-\" can be used as a file name to mean STDIN.\n");
877    
878    #ifdef SUPPORT_LIBZ
879    printf("Files whose names end in .gz are read using zlib.\n");
880    #endif
881    
882    #ifdef SUPPORT_LIBBZ2
883    printf("Files whose names end in .bz2 are read using bzlib2.\n");
884    #endif
885    
886    #if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2
887    printf("Other files and the standard input are read as plain files.\n\n");
888    #else
889    printf("All files are read as plain files, without any interpretation.\n\n");
890    #endif
891    
892    printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n");
893    printf("Options:\n");
894    
895    for (op = optionlist; op->one_char != 0; op++)
896      {
897      int n;
898      char s[4];
899    
900      /* Two options were accidentally implemented and documented with underscores
901      instead of hyphens in their names, something that was not noticed for quite a
902      few releases. When fixing this, I left the underscored versions in the list
903      in case people were using them. However, we don't want to display them in the
904      help data. There are no other options that contain underscores, and we do not
905      expect ever to implement such options. Therefore, just omit any option that
906      contains an underscore. */
907    
908      if (strchr(op->long_name, '_') != NULL) continue;
909    
910      if (op->one_char > 0 && (op->long_name)[0] == 0)
911        n = 31 - printf("  -%c", op->one_char);
912      else
913        {
914        if (op->one_char > 0) sprintf(s, "-%c,", op->one_char);
915          else strcpy(s, "   ");
916        n = 31 - printf("  %s --%s", s, op->long_name);
917        }
918    
919      if (n < 1) n = 1;
920      printf("%.*s%s\n", n, "                           ", op->help_text);
921      }
922    
923    printf("\nNumbers may be followed by K or M, e.g. --buffer-size=100K.\n");
924    printf("The default value for --buffer-size is %d.\n", PCREGREP_BUFSIZE);
925    printf("When reading patterns or file names from a file, trailing white\n");
926    printf("space is removed and blank lines are ignored.\n");
927    printf("The maximum size of any pattern is %d bytes.\n", MAXPATLEN);
928    
929    printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n");
930    printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n");
931    }
932    
933    
934    
935    /*************************************************
936  *            Test exclude/includes               *  *            Test exclude/includes               *
937  *************************************************/  *************************************************/
938    
# Line 818  return FALSE; Line 972  return FALSE;
972    
973    
974  /*************************************************  /*************************************************
975    *         Decode integer argument value          *
976    *************************************************/
977    
978    /* Integer arguments can be followed by K or M. Avoid the use of strtoul()
979    because SunOS4 doesn't have it. This is used only for unpicking arguments, so
980    just keep it simple.
981    
982    Arguments:
983      option_data   the option data string
984      op            the option item (for error messages)
985      longop        TRUE if option given in long form
986    
987    Returns:        a long integer
988    */
989    
990    static long int
991    decode_number(char *option_data, option_item *op, BOOL longop)
992    {
993    unsigned long int n = 0;
994    char *endptr = option_data;
995    while (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++;
996    while (isdigit((unsigned char)(*endptr)))
997      n = n * 10 + (int)(*endptr++ - '0');
998    if (toupper(*endptr) == 'K')
999      {
1000      n *= 1024;
1001      endptr++;
1002      }
1003    else if (toupper(*endptr) == 'M')
1004      {
1005      n *= 1024*1024;
1006      endptr++;
1007      }
1008    
1009    if (*endptr != 0)   /* Error */
1010      {
1011      if (longop)
1012        {
1013        char *equals = strchr(op->long_name, '=');
1014        int nlen = (equals == NULL)? (int)strlen(op->long_name) :
1015          (int)(equals - op->long_name);
1016        fprintf(stderr, "pcregrep: Malformed number \"%s\" after --%.*s\n",
1017          option_data, nlen, op->long_name);
1018        }
1019      else
1020        fprintf(stderr, "pcregrep: Malformed number \"%s\" after -%c\n",
1021          option_data, op->one_char);
1022      pcregrep_exit(usage(2));
1023      }
1024    
1025    return n;
1026    }
1027    
1028    
1029    
1030    /*************************************************
1031    *       Add item to a chain of numbers           *
1032    *************************************************/
1033    
1034    /* Used to add an item onto a chain, or just return an unconnected item if the
1035    "after" argument is NULL.
1036    
1037    Arguments:
1038      n          the number to add
1039      after      if not NULL points to item to insert after
1040    
1041    Returns:     new number block
1042    */
1043    
1044    static omstr *
1045    add_number(int n, omstr *after)
1046    {
1047    omstr *om = (omstr *)malloc(sizeof(omstr));
1048    
1049    if (om == NULL)
1050      {
1051      fprintf(stderr, "pcregrep: malloc failed\n");
1052      pcregrep_exit(2);
1053      }
1054    om->next = NULL;
1055    om->groupnum = n;
1056    
1057    if (after != NULL)
1058      {
1059      om->next = after->next;
1060      after->next = om;
1061      }
1062    return om;
1063    }
1064    
1065    
1066    
1067    /*************************************************
1068  *            Read one line of input              *  *            Read one line of input              *
1069  *************************************************/  *************************************************/
1070    
# Line 1001  switch(endlinetype) Line 1248  switch(endlinetype)
1248        case 0x2029:  /* Unicode PS */        case 0x2029:  /* Unicode PS */
1249        *lenptr = 3;        *lenptr = 3;
1250        return p;        return p;
1251  #endif  /* Not EBCDIC */  #endif  /* Not EBCDIC */
1252    
1253        default:        default:
1254        break;        break;
# Line 1060  switch(endlinetype) Line 1307  switch(endlinetype)
1307    
1308    while (p > startptr)    while (p > startptr)
1309      {      {
1310      register int c;      register unsigned int c;
1311      char *pp = p - 1;      char *pp = p - 1;
1312    
1313      if (utf8)      if (utf8)
# Line 1099  switch(endlinetype) Line 1346  switch(endlinetype)
1346        case '\v':    /* VT */        case '\v':    /* VT */
1347        case '\f':    /* FF */        case '\f':    /* FF */
1348        case '\r':    /* CR */        case '\r':    /* CR */
1349  #ifndef EBCDIE  #ifndef EBCDIE
1350        case 0x85:    /* Unicode NEL */        case 0x85:    /* Unicode NEL */
1351        case 0x2028:  /* Unicode LS */        case 0x2028:  /* Unicode LS */
1352        case 0x2029:  /* Unicode PS */        case 0x2029:  /* Unicode PS */
1353  #endif  /* Not EBCDIC */  #endif  /* Not EBCDIC */
1354        return p;        return p;
1355    
1356        default:        default:
# Line 1172  to find all possible matches. Line 1419  to find all possible matches.
1419  Arguments:  Arguments:
1420    matchptr     the start of the subject    matchptr     the start of the subject
1421    length       the length of the subject to match    length       the length of the subject to match
1422      options      options for pcre_exec
1423    startoffset  where to start matching    startoffset  where to start matching
1424    offsets      the offets vector to fill in    offsets      the offets vector to fill in
1425    mrc          address of where to put the result of pcre_exec()    mrc          address of where to put the result of pcre_exec()
# Line 1182  Returns:      TRUE if there was a match Line 1430  Returns:      TRUE if there was a match
1430  */  */
1431    
1432  static BOOL  static BOOL
1433  match_patterns(char *matchptr, size_t length, int startoffset, int *offsets,  match_patterns(char *matchptr, size_t length, unsigned int options,
1434    int *mrc)    int startoffset, int *offsets, int *mrc)
1435  {  {
1436  int i;  int i;
1437  size_t slen = length;  size_t slen = length;
# Line 1198  if (slen > 200) Line 1446  if (slen > 200)
1446  for (i = 1; p != NULL; p = p->next, i++)  for (i = 1; p != NULL; p = p->next, i++)
1447    {    {
1448    *mrc = pcre_exec(p->compiled, p->hint, matchptr, (int)length,    *mrc = pcre_exec(p->compiled, p->hint, matchptr, (int)length,
1449      startoffset, PCRE_NOTEMPTY, offsets, OFFSET_SIZE);      startoffset, options, offsets, OFFSET_SIZE);
1450    if (*mrc >= 0) return TRUE;    if (*mrc >= 0) return TRUE;
1451    if (*mrc == PCRE_ERROR_NOMATCH) continue;    if (*mrc == PCRE_ERROR_NOMATCH) continue;
1452    fprintf(stderr, "pcregrep: pcre_exec() gave error %d while matching ", *mrc);    fprintf(stderr, "pcregrep: pcre_exec() gave error %d while matching ", *mrc);
# Line 1281  of what we have. In the case of libz, a Line 1529  of what we have. In the case of libz, a
1529  plain file. However, if a .bz2 file isn't actually bzipped, the first read will  plain file. However, if a .bz2 file isn't actually bzipped, the first read will
1530  fail. */  fail. */
1531    
1532    (void)frtype;
1533    
1534  #ifdef SUPPORT_LIBZ  #ifdef SUPPORT_LIBZ
1535  if (frtype == FR_LIBZ)  if (frtype == FR_LIBZ)
1536    {    {
# Line 1331  while (ptr < endptr) Line 1581  while (ptr < endptr)
1581    int endlinelength;    int endlinelength;
1582    int mrc = 0;    int mrc = 0;
1583    int startoffset = 0;    int startoffset = 0;
1584      unsigned int options = 0;
1585    BOOL match;    BOOL match;
1586    char *matchptr = ptr;    char *matchptr = ptr;
1587    char *t = ptr;    char *t = ptr;
# Line 1367  while (ptr < endptr) Line 1618  while (ptr < endptr)
1618  #ifdef JFRIEDL_DEBUG  #ifdef JFRIEDL_DEBUG
1619    if (jfriedl_XT || jfriedl_XR)    if (jfriedl_XT || jfriedl_XR)
1620    {    {
1621        #include <sys/time.h>  #     include <sys/time.h>
1622        #include <time.h>  #     include <time.h>
1623        struct timeval start_time, end_time;        struct timeval start_time, end_time;
1624        struct timezone dummy;        struct timezone dummy;
1625        int i;        int i;
# Line 1412  while (ptr < endptr) Line 1663  while (ptr < endptr)
1663    }    }
1664  #endif  #endif
1665    
1666    /* We come back here after a match when the -o option (only_matching) is set,    /* We come back here after a match when show_only_matching is set, in order
1667    in order to find any further matches in the same line. */    to find any further matches in the same line. This applies to
1668      --only-matching, --file-offsets, and --line-offsets. */
1669    
1670    ONLY_MATCHING_RESTART:    ONLY_MATCHING_RESTART:
1671    
1672    /* Run through all the patterns until one matches or there is an error other    /* Run through all the patterns until one matches or there is an error other
1673    than NOMATCH. This code is in a subroutine so that it can be re-used for    than NOMATCH. This code is in a subroutine so that it can be re-used for
1674    finding subsequent matches when colouring matched lines. */    finding subsequent matches when colouring matched lines. After finding one
1675      match, set PCRE_NOTEMPTY to disable any further matches of null strings in
1676      this line. */
1677    
1678    match = match_patterns(matchptr, length, startoffset, offsets, &mrc);    match = match_patterns(matchptr, length, options, startoffset, offsets, &mrc);
1679      options = PCRE_NOTEMPTY;
1680    
1681    /* 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. */
1682    
# Line 1460  while (ptr < endptr) Line 1715  while (ptr < endptr)
1715    
1716      else if (quiet) return 0;      else if (quiet) return 0;
1717    
1718      /* The --only-matching option prints just the substring that matched, or a      /* The --only-matching option prints just the substring that matched,
1719      captured portion of it, as long as this string is not empty, and the      and/or one or more captured portions of it, as long as these strings are
1720      --file-offsets and --line-offsets options output offsets for the matching      not empty. The --file-offsets and --line-offsets options output offsets for
1721      substring (they both force --only-matching = 0). None of these options      the matching substring (all three set show_only_matching). None of these
1722      prints any context. Afterwards, adjust the start and then jump back to look      mutually exclusive options prints any context. Afterwards, adjust the start
1723      for further matches in the same line. If we are in invert mode, however,      and then jump back to look for further matches in the same line. If we are
1724      nothing is printed and we do not restart - this could still be useful      in invert mode, however, nothing is printed and we do not restart - this
1725      because the return code is set. */      could still be useful because the return code is set. */
1726    
1727      else if (only_matching >= 0)      else if (show_only_matching)
1728        {        {
1729        if (!invert)        if (!invert)
1730          {          {
1731          if (printname != NULL) fprintf(stdout, "%s:", printname);          if (printname != NULL) fprintf(stdout, "%s:", printname);
1732          if (number) fprintf(stdout, "%d:", linenumber);          if (number) fprintf(stdout, "%d:", linenumber);
1733    
1734            /* Handle --line-offsets */
1735    
1736          if (line_offsets)          if (line_offsets)
1737            fprintf(stdout, "%d,%d\n", (int)(matchptr + offsets[0] - ptr),            fprintf(stdout, "%d,%d\n", (int)(matchptr + offsets[0] - ptr),
1738              offsets[1] - offsets[0]);              offsets[1] - offsets[0]);
1739    
1740            /* Handle --file-offsets */
1741    
1742          else if (file_offsets)          else if (file_offsets)
1743            fprintf(stdout, "%d,%d\n",            fprintf(stdout, "%d,%d\n",
1744              (int)(filepos + matchptr + offsets[0] - ptr),              (int)(filepos + matchptr + offsets[0] - ptr),
1745              offsets[1] - offsets[0]);              offsets[1] - offsets[0]);
1746          else if (only_matching < mrc)  
1747            /* Handle --only-matching, which may occur many times */
1748    
1749            else
1750            {            {
1751            int plen = offsets[2*only_matching + 1] - offsets[2*only_matching];            BOOL printed = FALSE;
1752            if (plen > 0)            omstr *om;
1753    
1754              for (om = only_matching; om != NULL; om = om->next)
1755              {              {
1756              if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string);              int n = om->groupnum;
1757              FWRITE(matchptr + offsets[only_matching*2], 1, plen, stdout);              if (n < mrc)
1758              if (do_colour) fprintf(stdout, "%c[00m", 0x1b);                {
1759              fprintf(stdout, "\n");                int plen = offsets[2*n + 1] - offsets[2*n];
1760                  if (plen > 0)
1761                    {
1762                    if (printed) fprintf(stdout, "%s", om_separator);
1763                    if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1764                    FWRITE(matchptr + offsets[n*2], 1, plen, stdout);
1765                    if (do_colour) fprintf(stdout, "%c[00m", 0x1b);
1766                    printed = TRUE;
1767                    }
1768                  }
1769              }              }
1770    
1771              if (printed || printname != NULL || number) fprintf(stdout, "\n");
1772            }            }
1773          else if (printname != NULL || number) fprintf(stdout, "\n");  
1774            /* Prepare to repeat to find the next match */
1775    
1776          match = FALSE;          match = FALSE;
1777          if (line_buffered) fflush(stdout);          if (line_buffered) fflush(stdout);
1778          rc = 0;                      /* Had some success */          rc = 0;                      /* Had some success */
# Line 1597  while (ptr < endptr) Line 1876  while (ptr < endptr)
1876          {          {
1877          char *endmatch = ptr + offsets[1];          char *endmatch = ptr + offsets[1];
1878          t = ptr;          t = ptr;
1879          while (t < endmatch)          while (t <= endmatch)
1880            {            {
1881            t = end_of_line(t, endptr, &endlinelength);            t = end_of_line(t, endptr, &endlinelength);
1882            if (t < endmatch) linenumber++; else break;            if (t < endmatch) linenumber++; else break;
# Line 1638  while (ptr < endptr) Line 1917  while (ptr < endptr)
1917            {            {
1918            startoffset = offsets[1];            startoffset = offsets[1];
1919            if (startoffset >= (int)linelength + endlinelength ||            if (startoffset >= (int)linelength + endlinelength ||
1920                !match_patterns(matchptr, length, startoffset, offsets, &mrc))                !match_patterns(matchptr, length, options, startoffset, offsets,
1921                    &mrc))
1922              break;              break;
1923            FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout);            FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout);
1924            fprintf(stdout, "%c[%sm", 0x1b, colour_string);            fprintf(stdout, "%c[%sm", 0x1b, colour_string);
# Line 1756  while (ptr < endptr) Line 2036  while (ptr < endptr)
2036  /* End of file; print final "after" lines if wanted; do_after_lines sets  /* End of file; print final "after" lines if wanted; do_after_lines sets
2037  hyphenpending if it prints something. */  hyphenpending if it prints something. */
2038    
2039  if (only_matching < 0 && !count_only)  if (!show_only_matching && !count_only)
2040    {    {
2041    do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);    do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);
2042    hyphenpending |= endhyphenpending;    hyphenpending |= endhyphenpending;
# Line 1829  BZFILE *inbz2 = NULL; Line 2109  BZFILE *inbz2 = NULL;
2109  int pathlen;  int pathlen;
2110  #endif  #endif
2111    
2112    #if defined NATIVE_ZOS
2113    int zos_type;
2114    FILE *zos_test_file;
2115    #endif
2116    
2117  /* If the file name is "-" we scan stdin */  /* If the file name is "-" we scan stdin */
2118    
2119  if (strcmp(pathname, "-") == 0)  if (strcmp(pathname, "-") == 0)
# Line 1849  lastcomp = (lastcomp == NULL)? pathname Line 2134  lastcomp = (lastcomp == NULL)? pathname
2134  Otherwise, scan the directory and recurse for each path within it. The scanning  Otherwise, scan the directory and recurse for each path within it. The scanning
2135  code is localized so it can be made system-specific. */  code is localized so it can be made system-specific. */
2136    
2137    
2138    /* For z/OS, determine the file type. */
2139    
2140    #if defined NATIVE_ZOS
2141    zos_test_file =  fopen(pathname,"rb");
2142    
2143    if (zos_test_file == NULL)
2144       {
2145       if (!silent) fprintf(stderr, "pcregrep: failed to test next file %s\n",
2146         pathname, strerror(errno));
2147       return -1;
2148       }
2149    zos_type = identifyzosfiletype (zos_test_file);
2150    fclose (zos_test_file);
2151    
2152    /* Handle a PDS in separate code */
2153    
2154    if (zos_type == __ZOS_PDS || zos_type == __ZOS_PDSE)
2155       {
2156       return travelonpdsdir (pathname, only_one_at_top);
2157       }
2158    
2159    /* Deal with regular files in the normal way below. These types are:
2160       zos_type == __ZOS_PDS_MEMBER
2161       zos_type == __ZOS_PS
2162       zos_type == __ZOS_VSAM_KSDS
2163       zos_type == __ZOS_VSAM_ESDS
2164       zos_type == __ZOS_VSAM_RRDS
2165    */
2166    
2167    /* Handle a z/OS directory using common code. */
2168    
2169    else if (zos_type == __ZOS_HFS)
2170     {
2171    #endif  /* NATIVE_ZOS */
2172    
2173    
2174    /* Handle directories: common code for all OS */
2175    
2176  if (isdirectory(pathname))  if (isdirectory(pathname))
2177    {    {
2178    if (dee_action == dee_SKIP ||    if (dee_action == dee_SKIP ||
# Line 1883  if (isdirectory(pathname)) Line 2207  if (isdirectory(pathname))
2207      }      }
2208    }    }
2209    
2210  /* If the file is not a directory and not a regular file, skip it if that's  #if defined NATIVE_ZOS
2211  been requested. Otherwise, check for explicit include/exclude. */   }
2212    #endif
2213    
2214  else if ((!isregfile(pathname) && DEE_action == DEE_SKIP) ||  /* If the file is not a directory, check for a regular file, and if it is not,
2215            !test_incexc(lastcomp, include_patterns, exclude_patterns))  skip it if that's been requested. Otherwise, check for an explicit inclusion or
2216          return -1;  exclusion. */
2217    
2218    else if (
2219    #if defined NATIVE_ZOS
2220            (zos_type == __ZOS_NOFILE && DEE_action == DEE_SKIP) ||
2221    #else  /* all other OS */
2222            (!isregfile(pathname) && DEE_action == DEE_SKIP) ||
2223    #endif
2224            !test_incexc(lastcomp, include_patterns, exclude_patterns))
2225      return -1;  /* File skipped */
2226    
2227  /* Control reaches here if we have a regular file, or if we have a directory  /* Control reaches here if we have a regular file, or if we have a directory
2228  and recursion or skipping was not requested, or if we have anything else and  and recursion or skipping was not requested, or if we have anything else and
# Line 2003  return rc; Line 2337  return rc;
2337    
2338    
2339    
   
 /*************************************************  
 *                Usage function                  *  
 *************************************************/  
   
 static int  
 usage(int rc)  
 {  
 option_item *op;  
 fprintf(stderr, "Usage: pcregrep [-");  
 for (op = optionlist; op->one_char != 0; op++)  
   {  
   if (op->one_char > 0) fprintf(stderr, "%c", op->one_char);  
   }  
 fprintf(stderr, "] [long options] [pattern] [files]\n");  
 fprintf(stderr, "Type `pcregrep --help' for more information and the long "  
   "options.\n");  
 return rc;  
 }  
   
   
   
   
 /*************************************************  
 *                Help function                   *  
 *************************************************/  
   
 static void  
 help(void)  
 {  
 option_item *op;  
   
 printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n");  
 printf("Search for PATTERN in each FILE or standard input.\n");  
 printf("PATTERN must be present if neither -e nor -f is used.\n");  
 printf("\"-\" can be used as a file name to mean STDIN.\n");  
   
 #ifdef SUPPORT_LIBZ  
 printf("Files whose names end in .gz are read using zlib.\n");  
 #endif  
   
 #ifdef SUPPORT_LIBBZ2  
 printf("Files whose names end in .bz2 are read using bzlib2.\n");  
 #endif  
   
 #if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2  
 printf("Other files and the standard input are read as plain files.\n\n");  
 #else  
 printf("All files are read as plain files, without any interpretation.\n\n");  
 #endif  
   
 printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n");  
 printf("Options:\n");  
   
 for (op = optionlist; op->one_char != 0; op++)  
   {  
   int n;  
   char s[4];  
   
   /* Two options were accidentally implemented and documented with underscores  
   instead of hyphens in their names, something that was not noticed for quite a  
   few releases. When fixing this, I left the underscored versions in the list  
   in case people were using them. However, we don't want to display them in the  
   help data. There are no other options that contain underscores, and we do not  
   expect ever to implement such options. Therefore, just omit any option that  
   contains an underscore. */  
   
   if (strchr(op->long_name, '_') != NULL) continue;  
   
   if (op->one_char > 0 && (op->long_name)[0] == 0)  
     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;  
   printf("%.*s%s\n", n, "                           ", op->help_text);  
   }  
   
 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("When reading patterns or file names from a file, trailing white\n");  
 printf("space is removed and blank lines are ignored.\n");  
 printf("The maximum size of any pattern is %d bytes.\n", MAXPATLEN);  
   
 printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n");  
 printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n");  
 }  
   
   
   
   
2340  /*************************************************  /*************************************************
2341  *    Handle a single-letter, no data option      *  *    Handle a single-letter, no data option      *
2342  *************************************************/  *************************************************/
# Line 2123  switch(letter) Line 2362  switch(letter)
2362    case 'L': filenames = FN_NOMATCH_ONLY; break;    case 'L': filenames = FN_NOMATCH_ONLY; break;
2363    case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break;    case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break;
2364    case 'n': number = TRUE; break;    case 'n': number = TRUE; break;
2365    case 'o': only_matching = 0; break;  
2366      case 'o':
2367      only_matching_last = add_number(0, only_matching_last);
2368      if (only_matching == NULL) only_matching = only_matching_last;
2369      break;
2370    
2371    case 'q': quiet = TRUE; break;    case 'q': quiet = TRUE; break;
2372    case 'r': dee_action = dee_RECURSE; break;    case 'r': dee_action = dee_RECURSE; break;
2373    case 's': silent = TRUE; break;    case 's': silent = TRUE; break;
# Line 2509  for (i = 1; i < argc; i++) Line 2753  for (i = 1; i < argc; i++)
2753      {      {
2754      char *s = argv[i] + 1;      char *s = argv[i] + 1;
2755      longop = FALSE;      longop = FALSE;
2756    
2757      while (*s != 0)      while (*s != 0)
2758        {        {
2759        for (op = optionlist; op->one_char != 0; op++)        for (op = optionlist; op->one_char != 0; op++)
# Line 2522  for (i = 1; i < argc; i++) Line 2767  for (i = 1; i < argc; i++)
2767          pcregrep_exit(usage(2));          pcregrep_exit(usage(2));
2768          }          }
2769    
2770        /* Check for a single-character option that has data: OP_OP_NUMBER        option_data = s+1;
2771        is used for one that either has a numerical number or defaults, i.e. the  
2772        data is optional. If a digit follows, there is data; if not, carry on        /* Break out if this is the last character in the string; it's handled
2773          below like a single multi-char option. */
2774    
2775          if (*option_data == 0) break;
2776    
2777          /* Check for a single-character option that has data: OP_OP_NUMBER(S)
2778          are used for ones that either have a numerical number or defaults, i.e.
2779          the data is optional. If a digit follows, there is data; if not, carry on
2780        with other single-character options in the same string. */        with other single-character options in the same string. */
2781    
2782        option_data = s+1;        if (op->type == OP_OP_NUMBER || op->type == OP_OP_NUMBERS)
       if (op->type == OP_OP_NUMBER)  
2783          {          {
2784          if (isdigit((unsigned char)s[1])) break;          if (isdigit((unsigned char)s[1])) break;
2785          }          }
2786        else   /* Check for end or a dataless option */        else   /* Check for an option with data */
2787          {          {
2788          if (op->type != OP_NODATA || s[1] == 0) break;          if (op->type != OP_NODATA) break;
2789          }          }
2790    
2791        /* Handle a single-character option with no data, then loop for the        /* Handle a single-character option with no data, then loop for the
# Line 2554  for (i = 1; i < argc; i++) Line 2805  for (i = 1; i < argc; i++)
2805      continue;      continue;
2806      }      }
2807    
2808    /* If the option type is OP_OP_STRING or OP_OP_NUMBER, it's an option that    /* If the option type is OP_OP_STRING or OP_OP_NUMBER(S), it's an option that
2809    either has a value or defaults to something. It cannot have data in a    either has a value or defaults to something. It cannot have data in a
2810    separate item. At the moment, the only such options are "colo(u)r",    separate item. At the moment, the only such options are "colo(u)r",
2811    "only-matching", and Jeffrey Friedl's special -S debugging option. */    "only-matching", and Jeffrey Friedl's special -S debugging option. */
2812    
2813    if (*option_data == 0 &&    if (*option_data == 0 &&
2814        (op->type == OP_OP_STRING || op->type == OP_OP_NUMBER))        (op->type == OP_OP_STRING || op->type == OP_OP_NUMBER ||
2815           op->type == OP_OP_NUMBERS))
2816      {      {
2817      switch (op->one_char)      switch (op->one_char)
2818        {        {
# Line 2569  for (i = 1; i < argc; i++) Line 2821  for (i = 1; i < argc; i++)
2821        break;        break;
2822    
2823        case 'o':        case 'o':
2824        only_matching = 0;        only_matching_last = add_number(0, only_matching_last);
2825          if (only_matching == NULL) only_matching = only_matching_last;
2826        break;        break;
2827    
2828  #ifdef JFRIEDL_DEBUG  #ifdef JFRIEDL_DEBUG
# Line 2593  for (i = 1; i < argc; i++) Line 2846  for (i = 1; i < argc; i++)
2846      option_data = argv[++i];      option_data = argv[++i];
2847      }      }
2848    
2849      /* If the option type is OP_OP_NUMBERS, the value is a number that is to be
2850      added to a chain of numbers. */
2851    
2852      if (op->type == OP_OP_NUMBERS)
2853        {
2854        unsigned long int n = decode_number(option_data, op, longop);
2855        omdatastr *omd = (omdatastr *)op->dataptr;
2856        *(omd->lastptr) = add_number((int)n, *(omd->lastptr));
2857        if (*(omd->anchor) == NULL) *(omd->anchor) = *(omd->lastptr);
2858        }
2859    
2860    /* If the option type is OP_PATLIST, it's the -e option, or one of the    /* If the option type is OP_PATLIST, it's the -e option, or one of the
2861    include/exclude options, which can be called multiple times to create lists    include/exclude options, which can be called multiple times to create lists
2862    of patterns. */    of patterns. */
2863    
2864    if (op->type == OP_PATLIST)    else if (op->type == OP_PATLIST)
2865       {      {
2866       patdatastr *pd = (patdatastr *)op->dataptr;      patdatastr *pd = (patdatastr *)op->dataptr;
2867       *(pd->lastptr) = add_pattern(option_data, *(pd->lastptr));      *(pd->lastptr) = add_pattern(option_data, *(pd->lastptr));
2868       if (*(pd->lastptr) == NULL) goto EXIT2;      if (*(pd->lastptr) == NULL) goto EXIT2;
2869       if (*(pd->anchor) == NULL) *(pd->anchor) = *(pd->lastptr);      if (*(pd->anchor) == NULL) *(pd->anchor) = *(pd->lastptr);
2870       }      }
2871    
2872    /* If the option type is OP_FILELIST, it's one of the options that names a    /* If the option type is OP_FILELIST, it's one of the options that names a
2873    file. */    file. */
# Line 2644  for (i = 1; i < argc; i++) Line 2908  for (i = 1; i < argc; i++)
2908        }        }
2909      }      }
2910    
2911    /* Otherwise, deal with single string or numeric data values. */    /* Otherwise, deal with a single string or numeric data value. */
2912    
2913    else if (op->type != OP_NUMBER && op->type != OP_LONGNUMBER &&    else if (op->type != OP_NUMBER && op->type != OP_LONGNUMBER &&
2914             op->type != OP_OP_NUMBER)             op->type != OP_OP_NUMBER)
2915      {      {
2916      *((char **)op->dataptr) = option_data;      *((char **)op->dataptr) = option_data;
2917      }      }
   
   /* Avoid the use of strtoul() because SunOS4 doesn't have it. This is used  
   only for unpicking arguments, so just keep it simple. */  
   
2918    else    else
2919      {      {
2920      unsigned long int n = 0;      unsigned long int n = decode_number(option_data, op, longop);
2921      char *endptr = option_data;      if (op->type == OP_LONGNUMBER) *((unsigned long int *)op->dataptr) = n;
2922      while (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++;        else *((int *)op->dataptr) = n;
     while (isdigit((unsigned char)(*endptr)))  
       n = n * 10 + (int)(*endptr++ - '0');  
     if (toupper(*endptr) == 'K')  
       {  
       n *= 1024;  
       endptr++;  
       }  
     else if (toupper(*endptr) == 'M')  
       {  
       n *= 1024*1024;  
       endptr++;  
       }  
     if (*endptr != 0)  
       {  
       if (longop)  
         {  
         char *equals = strchr(op->long_name, '=');  
         int nlen = (equals == NULL)? (int)strlen(op->long_name) :  
           (int)(equals - op->long_name);  
         fprintf(stderr, "pcregrep: Malformed number \"%s\" after --%.*s\n",  
           option_data, nlen, op->long_name);  
         }  
       else  
         fprintf(stderr, "pcregrep: Malformed number \"%s\" after -%c\n",  
           option_data, op->one_char);  
       pcregrep_exit(usage(2));  
       }  
     if (op->type == OP_LONGNUMBER)  
         *((unsigned long int *)op->dataptr) = n;  
     else  
         *((int *)op->dataptr) = n;  
2923      }      }
2924    }    }
2925    
# Line 2704  if (both_context > 0) Line 2933  if (both_context > 0)
2933    }    }
2934    
2935  /* Only one of --only-matching, --file-offsets, or --line-offsets is permitted.  /* Only one of --only-matching, --file-offsets, or --line-offsets is permitted.
2936  However, the latter two set only_matching. */  However, all three set show_only_matching because they display, each in their
2937    own way, only the data that has matched. */
2938    
2939  if ((only_matching >= 0 && (file_offsets || line_offsets)) ||  if ((only_matching != NULL && (file_offsets || line_offsets)) ||
2940      (file_offsets && line_offsets))      (file_offsets && line_offsets))
2941    {    {
2942    fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets "    fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets "
# Line 2714  if ((only_matching >= 0 && (file_offsets Line 2944  if ((only_matching >= 0 && (file_offsets
2944    pcregrep_exit(usage(2));    pcregrep_exit(usage(2));
2945    }    }
2946    
2947  if (file_offsets || line_offsets) only_matching = 0;  if (only_matching != NULL || file_offsets || line_offsets)
2948      show_only_matching = TRUE;
2949    
2950  /* 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
2951  LC_ALL environment variable is set, and if so, use it. */  LC_ALL environment variable is set, and if so, use it. */
# Line 2880  for (fn = pattern_files; fn != NULL; fn Line 3111  for (fn = pattern_files; fn != NULL; fn
3111      goto EXIT2;      goto EXIT2;
3112    }    }
3113    
3114  /* Study the regular expressions, as we will be running them many times. Unless  /* Study the regular expressions, as we will be running them many times. If an
3115  JIT has been explicitly disabled, arrange a stack for it to use. */  extra block is needed for a limit, set PCRE_STUDY_EXTRA_NEEDED so that one is
3116    returned, even if studying produces no data. */
3117    
3118    if (match_limit > 0 || match_limit_recursion > 0)
3119      study_options |= PCRE_STUDY_EXTRA_NEEDED;
3120    
3121    /* Unless JIT has been explicitly disabled, arrange a stack for it to use. */
3122    
3123  #ifdef SUPPORT_PCREGREP_JIT  #ifdef SUPPORT_PCREGREP_JIT
3124  if ((study_options & PCRE_STUDY_JIT_COMPILE) != 0)  if ((study_options & PCRE_STUDY_JIT_COMPILE) != 0)
# Line 2905  for (j = 1, cp = patterns; cp != NULL; j Line 3142  for (j = 1, cp = patterns; cp != NULL; j
3142    }    }
3143    
3144  /* If --match-limit or --recursion-limit was set, put the value(s) into the  /* If --match-limit or --recursion-limit was set, put the value(s) into the
3145  pcre_extra block for each pattern. */  pcre_extra block for each pattern. There will always be an extra block because
3146    of the use of PCRE_STUDY_EXTRA_NEEDED above. */
3147    
3148  if (match_limit > 0 || match_limit_recursion > 0)  for (cp = patterns; cp != NULL; cp = cp->next)
3149    {    {
3150    for (cp = patterns; cp != NULL; cp = cp->next)    if (match_limit > 0)
3151      {      {
3152      if (cp->hint == NULL)      cp->hint->flags |= PCRE_EXTRA_MATCH_LIMIT;
3153        {      cp->hint->match_limit = match_limit;
3154        cp->hint = (pcre_extra *)malloc(sizeof(pcre_extra));      }
3155        if (cp->hint == NULL)  
3156          {    if (match_limit_recursion > 0)
3157          fprintf(stderr, "pcregrep: malloc failed\n");      {
3158          pcregrep_exit(2);      cp->hint->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
3159          }      cp->hint->match_limit_recursion = match_limit_recursion;
       }  
     if (match_limit > 0)  
       {  
       cp->hint->flags |= PCRE_EXTRA_MATCH_LIMIT;  
       cp->hint->match_limit = match_limit;  
       }  
     if (match_limit_recursion > 0)  
       {  
       cp->hint->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;  
       cp->hint->match_limit_recursion = match_limit_recursion;  
       }  
3160      }      }
3161    }    }
3162    
# Line 3037  free_file_chain(include_from); Line 3264  free_file_chain(include_from);
3264  free_file_chain(pattern_files);  free_file_chain(pattern_files);
3265  free_file_chain(file_lists);  free_file_chain(file_lists);
3266    
3267    while (only_matching != NULL)
3268      {
3269      omstr *this = only_matching;
3270      only_matching = this->next;
3271      free(this);
3272      }
3273    
3274  pcregrep_exit(rc);  pcregrep_exit(rc);
3275    
3276  EXIT2:  EXIT2:

Legend:
Removed from v.1033  
changed lines
  Added in v.1355

  ViewVC Help
Powered by ViewVC 1.1.5