/[pcre]/code/tags/pcre-8.01/pcregrep.c
ViewVC logotype

Diff of /code/tags/pcre-8.01/pcregrep.c

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

revision 91 by nigel, Sat Feb 24 21:41:34 2007 UTC revision 283 by ph10, Fri Dec 7 19:59:19 2007 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-2006 University of Cambridge             Copyright (c) 1997-2007 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 37  POSSIBILITY OF SUCH DAMAGE. Line 37  POSSIBILITY OF SUCH DAMAGE.
37  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
38  */  */
39    
40    #ifdef HAVE_CONFIG_H
41    #include "config.h"
42    #endif
43    
44  #include <ctype.h>  #include <ctype.h>
45  #include <locale.h>  #include <locale.h>
46  #include <stdio.h>  #include <stdio.h>
# Line 46  POSSIBILITY OF SUCH DAMAGE. Line 50  POSSIBILITY OF SUCH DAMAGE.
50    
51  #include <sys/types.h>  #include <sys/types.h>
52  #include <sys/stat.h>  #include <sys/stat.h>
53    
54    #ifdef HAVE_UNISTD_H
55  #include <unistd.h>  #include <unistd.h>
56    #endif
57    
 #include "config.h"  
58  #include "pcre.h"  #include "pcre.h"
59    
60  #define FALSE 0  #define FALSE 0
# Line 56  POSSIBILITY OF SUCH DAMAGE. Line 62  POSSIBILITY OF SUCH DAMAGE.
62    
63  typedef int BOOL;  typedef int BOOL;
64    
 #define VERSION "4.3 01-Jun-2006"  
65  #define MAX_PATTERN_COUNT 100  #define MAX_PATTERN_COUNT 100
66    
67  #if BUFSIZ > 8192  #if BUFSIZ > 8192
# Line 65  typedef int BOOL; Line 70  typedef int BOOL;
70  #define MBUFTHIRD 8192  #define MBUFTHIRD 8192
71  #endif  #endif
72    
   
73  /* Values for the "filenames" variable, which specifies options for file name  /* Values for the "filenames" variable, which specifies options for file name
74  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
75  all values greater than FN_DEFAULT. */  all values greater than FN_DEFAULT. */
# Line 83  enum { DEE_READ, DEE_SKIP }; Line 87  enum { DEE_READ, DEE_SKIP };
87  #define PO_LINE_MATCH     0x0002  #define PO_LINE_MATCH     0x0002
88  #define PO_FIXED_STRINGS  0x0004  #define PO_FIXED_STRINGS  0x0004
89    
90    /* Line ending types */
91    
92    enum { EL_LF, EL_CR, EL_CRLF, EL_ANY, EL_ANYCRLF };
93    
94    
95    
96  /*************************************************  /*************************************************
# Line 100  static const char *jfriedl_prefix = ""; Line 108  static const char *jfriedl_prefix = "";
108  static const char *jfriedl_postfix = "";  static const char *jfriedl_postfix = "";
109  #endif  #endif
110    
111  static int  endlinebyte = '\n';     /* Last byte of endline sequence */  static int  endlinetype;
 static int  endlineextra = 0;       /* Extra bytes for endline sequence */  
112    
113  static char *colour_string = (char *)"1;31";  static char *colour_string = (char *)"1;31";
114  static char *colour_option = NULL;  static char *colour_option = NULL;
# Line 115  static char *locale = NULL; Line 122  static char *locale = NULL;
122  static const unsigned char *pcretables = NULL;  static const unsigned char *pcretables = NULL;
123    
124  static int  pattern_count = 0;  static int  pattern_count = 0;
125  static pcre **pattern_list;  static pcre **pattern_list = NULL;
126  static pcre_extra **hints_list;  static pcre_extra **hints_list = NULL;
127    
128  static char *include_pattern = NULL;  static char *include_pattern = NULL;
129  static char *exclude_pattern = NULL;  static char *exclude_pattern = NULL;
# Line 135  static int process_options = 0; Line 142  static int process_options = 0;
142    
143  static BOOL count_only = FALSE;  static BOOL count_only = FALSE;
144  static BOOL do_colour = FALSE;  static BOOL do_colour = FALSE;
145    static BOOL file_offsets = FALSE;
146  static BOOL hyphenpending = FALSE;  static BOOL hyphenpending = FALSE;
147  static BOOL invert = FALSE;  static BOOL invert = FALSE;
148    static BOOL line_offsets = FALSE;
149  static BOOL multiline = FALSE;  static BOOL multiline = FALSE;
150  static BOOL number = FALSE;  static BOOL number = FALSE;
151  static BOOL only_matching = FALSE;  static BOOL only_matching = FALSE;
152  static BOOL quiet = FALSE;  static BOOL quiet = FALSE;
153  static BOOL silent = FALSE;  static BOOL silent = FALSE;
154    static BOOL utf8 = FALSE;
155    
156  /* Structure for options and list of them */  /* Structure for options and list of them */
157    
# Line 166  used to identify them. */ Line 176  used to identify them. */
176  #define N_LABEL     (-5)  #define N_LABEL     (-5)
177  #define N_LOCALE    (-6)  #define N_LOCALE    (-6)
178  #define N_NULL      (-7)  #define N_NULL      (-7)
179    #define N_LOFFSETS  (-8)
180    #define N_FOFFSETS  (-9)
181    
182  static option_item optionlist[] = {  static option_item optionlist[] = {
183    { OP_NODATA,    N_NULL,   NULL,              "",              "  terminate options" },    { OP_NODATA,    N_NULL,   NULL,              "",              "  terminate options" },
# Line 181  static option_item optionlist[] = { Line 193  static option_item optionlist[] = {
193    { OP_PATLIST,   'e',      NULL,              "regex(p)",      "specify pattern (may be used more than once)" },    { OP_PATLIST,   'e',      NULL,              "regex(p)",      "specify pattern (may be used more than once)" },
194    { 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" },
195    { OP_STRING,    'f',      &pattern_filename, "file=path",     "read patterns from file" },    { OP_STRING,    'f',      &pattern_filename, "file=path",     "read patterns from file" },
196      { OP_NODATA,    N_FOFFSETS, NULL,            "file-offsets",  "output file offsets, not text" },
197    { OP_NODATA,    'H',      NULL,              "with-filename", "force the prefixing filename on output" },    { OP_NODATA,    'H',      NULL,              "with-filename", "force the prefixing filename on output" },
198    { OP_NODATA,    'h',      NULL,              "no-filename",   "suppress the prefixing filename on output" },    { OP_NODATA,    'h',      NULL,              "no-filename",   "suppress the prefixing filename on output" },
199    { OP_NODATA,    'i',      NULL,              "ignore-case",   "ignore case distinctions" },    { OP_NODATA,    'i',      NULL,              "ignore-case",   "ignore case distinctions" },
200    { OP_NODATA,    'l',      NULL,              "files-with-matches", "print only FILE names containing matches" },    { OP_NODATA,    'l',      NULL,              "files-with-matches", "print only FILE names containing matches" },
201    { OP_NODATA,    'L',      NULL,              "files-without-match","print only FILE names not containing matches" },    { OP_NODATA,    'L',      NULL,              "files-without-match","print only FILE names not containing matches" },
202    { OP_STRING,    N_LABEL,  &stdin_name,       "label=name",    "set name for standard input" },    { OP_STRING,    N_LABEL,  &stdin_name,       "label=name",    "set name for standard input" },
203      { OP_NODATA,    N_LOFFSETS, NULL,            "line-offsets",  "output line numbers and offsets, not text" },
204    { OP_STRING,    N_LOCALE, &locale,           "locale=locale", "use the named locale" },    { OP_STRING,    N_LOCALE, &locale,           "locale=locale", "use the named locale" },
205    { OP_NODATA,    'M',      NULL,              "multiline",     "run in multiline mode" },    { OP_NODATA,    'M',      NULL,              "multiline",     "run in multiline mode" },
206    { OP_STRING,    'N',      &newline,          "newline=type",  "specify newline type (CR, LR, CRLF)" },    { OP_STRING,    'N',      &newline,          "newline=type",  "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" },
207    { OP_NODATA,    'n',      NULL,              "line-number",   "print line number with output lines" },    { OP_NODATA,    'n',      NULL,              "line-number",   "print line number with output lines" },
208    { OP_NODATA,    'o',      NULL,              "only-matching", "show only the part of the line that matched" },    { OP_NODATA,    'o',      NULL,              "only-matching", "show only the part of the line that matched" },
209    { OP_NODATA,    'q',      NULL,              "quiet",         "suppress output, just set return code" },    { OP_NODATA,    'q',      NULL,              "quiet",         "suppress output, just set return code" },
# Line 219  static const char *prefix[] = { Line 233  static const char *prefix[] = {
233  static const char *suffix[] = {  static const char *suffix[] = {
234    "", "\\b", ")$",   ")$",   "\\E", "\\E\\b", "\\E)$",   "\\E)$" };    "", "\\b", ")$",   ")$",   "\\E", "\\E\\b", "\\E)$",   "\\E)$" };
235    
236    /* UTF-8 tables - used only when the newline setting is "any". */
237    
238    const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
239    
240    const char utf8_table4[] = {
241      1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
242      1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
243      2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
244      3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
245    
246    
247    
248  /*************************************************  /*************************************************
# Line 231  although at present the only ones are fo Line 255  although at present the only ones are fo
255    
256  /************* Directory scanning in Unix ***********/  /************* Directory scanning in Unix ***********/
257    
258  #if IS_UNIX  #if defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H
259  #include <sys/types.h>  #include <sys/types.h>
260  #include <sys/stat.h>  #include <sys/stat.h>
261  #include <dirent.h>  #include <dirent.h>
# Line 263  for (;;) Line 287  for (;;)
287    if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0)    if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0)
288      return dent->d_name;      return dent->d_name;
289    }    }
290  return NULL;   /* Keep compiler happy; never executed */  /* Control never reaches here */
291  }  }
292    
293  static void  static void
# Line 298  return isatty(fileno(stdout)); Line 322  return isatty(fileno(stdout));
322    
323  /* 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
324  Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES  Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES
325  when it did not exist. */  when it did not exist. David Byron added a patch that moved the #include of
326    <windows.h> to before the INVALID_FILE_ATTRIBUTES definition rather than after.
327    */
328    
329  #elif HAVE_WIN32API  #elif HAVE_WINDOWS_H
330    
331  #ifndef STRICT  #ifndef STRICT
332  # define STRICT  # define STRICT
# Line 309  when it did not exist. */ Line 334  when it did not exist. */
334  #ifndef WIN32_LEAN_AND_MEAN  #ifndef WIN32_LEAN_AND_MEAN
335  # define WIN32_LEAN_AND_MEAN  # define WIN32_LEAN_AND_MEAN
336  #endif  #endif
337    
338    #include <windows.h>
339    
340  #ifndef INVALID_FILE_ATTRIBUTES  #ifndef INVALID_FILE_ATTRIBUTES
341  #define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF  #define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
342  #endif  #endif
343    
 #include <windows.h>  
   
344  typedef struct directory_type  typedef struct directory_type
345  {  {
346  HANDLE handle;  HANDLE handle;
# Line 399  regular if they are not directories. */ Line 425  regular if they are not directories. */
425    
426  int isregfile(char *filename)  int isregfile(char *filename)
427  {  {
428  return !isdirectory(filename)  return !isdirectory(filename);
429  }  }
430    
431    
# Line 410  return !isdirectory(filename) Line 436  return !isdirectory(filename)
436  static BOOL  static BOOL
437  is_stdout_tty(void)  is_stdout_tty(void)
438  {  {
439  FALSE;  return FALSE;
440  }  }
441    
442    
# Line 423  FALSE; Line 449  FALSE;
449  typedef void directory_type;  typedef void directory_type;
450    
451  int isdirectory(char *filename) { return 0; }  int isdirectory(char *filename) { return 0; }
452  directory_type * opendirectory(char *filename) {}  directory_type * opendirectory(char *filename) { return (directory_type*)0;}
453  char *readdirectory(directory_type *dir) {}  char *readdirectory(directory_type *dir) { return (char*)0;}
454  void closedirectory(directory_type *dir) {}  void closedirectory(directory_type *dir) {}
455    
456    
# Line 448  return FALSE; Line 474  return FALSE;
474    
475    
476    
477  #if ! HAVE_STRERROR  #ifndef HAVE_STRERROR
478  /*************************************************  /*************************************************
479  *     Provide strerror() for non-ANSI libraries  *  *     Provide strerror() for non-ANSI libraries  *
480  *************************************************/  *************************************************/
# Line 471  return sys_errlist[n]; Line 497  return sys_errlist[n];
497    
498    
499  /*************************************************  /*************************************************
500    *             Find end of line                   *
501    *************************************************/
502    
503    /* The length of the endline sequence that is found is set via lenptr. This may
504    be zero at the very end of the file if there is no line-ending sequence there.
505    
506    Arguments:
507      p         current position in line
508      endptr    end of available data
509      lenptr    where to put the length of the eol sequence
510    
511    Returns:    pointer to the last byte of the line
512    */
513    
514    static char *
515    end_of_line(char *p, char *endptr, int *lenptr)
516    {
517    switch(endlinetype)
518      {
519      default:      /* Just in case */
520      case EL_LF:
521      while (p < endptr && *p != '\n') p++;
522      if (p < endptr)
523        {
524        *lenptr = 1;
525        return p + 1;
526        }
527      *lenptr = 0;
528      return endptr;
529    
530      case EL_CR:
531      while (p < endptr && *p != '\r') p++;
532      if (p < endptr)
533        {
534        *lenptr = 1;
535        return p + 1;
536        }
537      *lenptr = 0;
538      return endptr;
539    
540      case EL_CRLF:
541      for (;;)
542        {
543        while (p < endptr && *p != '\r') p++;
544        if (++p >= endptr)
545          {
546          *lenptr = 0;
547          return endptr;
548          }
549        if (*p == '\n')
550          {
551          *lenptr = 2;
552          return p + 1;
553          }
554        }
555      break;
556    
557      case EL_ANYCRLF:
558      while (p < endptr)
559        {
560        int extra = 0;
561        register int c = *((unsigned char *)p);
562    
563        if (utf8 && c >= 0xc0)
564          {
565          int gcii, gcss;
566          extra = utf8_table4[c & 0x3f];  /* Number of additional bytes */
567          gcss = 6*extra;
568          c = (c & utf8_table3[extra]) << gcss;
569          for (gcii = 1; gcii <= extra; gcii++)
570            {
571            gcss -= 6;
572            c |= (p[gcii] & 0x3f) << gcss;
573            }
574          }
575    
576        p += 1 + extra;
577    
578        switch (c)
579          {
580          case 0x0a:    /* LF */
581          *lenptr = 1;
582          return p;
583    
584          case 0x0d:    /* CR */
585          if (p < endptr && *p == 0x0a)
586            {
587            *lenptr = 2;
588            p++;
589            }
590          else *lenptr = 1;
591          return p;
592    
593          default:
594          break;
595          }
596        }   /* End of loop for ANYCRLF case */
597    
598      *lenptr = 0;  /* Must have hit the end */
599      return endptr;
600    
601      case EL_ANY:
602      while (p < endptr)
603        {
604        int extra = 0;
605        register int c = *((unsigned char *)p);
606    
607        if (utf8 && c >= 0xc0)
608          {
609          int gcii, gcss;
610          extra = utf8_table4[c & 0x3f];  /* Number of additional bytes */
611          gcss = 6*extra;
612          c = (c & utf8_table3[extra]) << gcss;
613          for (gcii = 1; gcii <= extra; gcii++)
614            {
615            gcss -= 6;
616            c |= (p[gcii] & 0x3f) << gcss;
617            }
618          }
619    
620        p += 1 + extra;
621    
622        switch (c)
623          {
624          case 0x0a:    /* LF */
625          case 0x0b:    /* VT */
626          case 0x0c:    /* FF */
627          *lenptr = 1;
628          return p;
629    
630          case 0x0d:    /* CR */
631          if (p < endptr && *p == 0x0a)
632            {
633            *lenptr = 2;
634            p++;
635            }
636          else *lenptr = 1;
637          return p;
638    
639          case 0x85:    /* NEL */
640          *lenptr = utf8? 2 : 1;
641          return p;
642    
643          case 0x2028:  /* LS */
644          case 0x2029:  /* PS */
645          *lenptr = 3;
646          return p;
647    
648          default:
649          break;
650          }
651        }   /* End of loop for ANY case */
652    
653      *lenptr = 0;  /* Must have hit the end */
654      return endptr;
655      }     /* End of overall switch */
656    }
657    
658    
659    
660    /*************************************************
661    *         Find start of previous line            *
662    *************************************************/
663    
664    /* This is called when looking back for before lines to print.
665    
666    Arguments:
667      p         start of the subsequent line
668      startptr  start of available data
669    
670    Returns:    pointer to the start of the previous line
671    */
672    
673    static char *
674    previous_line(char *p, char *startptr)
675    {
676    switch(endlinetype)
677      {
678      default:      /* Just in case */
679      case EL_LF:
680      p--;
681      while (p > startptr && p[-1] != '\n') p--;
682      return p;
683    
684      case EL_CR:
685      p--;
686      while (p > startptr && p[-1] != '\n') p--;
687      return p;
688    
689      case EL_CRLF:
690      for (;;)
691        {
692        p -= 2;
693        while (p > startptr && p[-1] != '\n') p--;
694        if (p <= startptr + 1 || p[-2] == '\r') return p;
695        }
696      return p;   /* But control should never get here */
697    
698      case EL_ANY:
699      case EL_ANYCRLF:
700      if (*(--p) == '\n' && p > startptr && p[-1] == '\r') p--;
701      if (utf8) while ((*p & 0xc0) == 0x80) p--;
702    
703      while (p > startptr)
704        {
705        register int c;
706        char *pp = p - 1;
707    
708        if (utf8)
709          {
710          int extra = 0;
711          while ((*pp & 0xc0) == 0x80) pp--;
712          c = *((unsigned char *)pp);
713          if (c >= 0xc0)
714            {
715            int gcii, gcss;
716            extra = utf8_table4[c & 0x3f];  /* Number of additional bytes */
717            gcss = 6*extra;
718            c = (c & utf8_table3[extra]) << gcss;
719            for (gcii = 1; gcii <= extra; gcii++)
720              {
721              gcss -= 6;
722              c |= (pp[gcii] & 0x3f) << gcss;
723              }
724            }
725          }
726        else c = *((unsigned char *)pp);
727    
728        if (endlinetype == EL_ANYCRLF) switch (c)
729          {
730          case 0x0a:    /* LF */
731          case 0x0d:    /* CR */
732          return p;
733    
734          default:
735          break;
736          }
737    
738        else switch (c)
739          {
740          case 0x0a:    /* LF */
741          case 0x0b:    /* VT */
742          case 0x0c:    /* FF */
743          case 0x0d:    /* CR */
744          case 0x85:    /* NEL */
745          case 0x2028:  /* LS */
746          case 0x2029:  /* PS */
747          return p;
748    
749          default:
750          break;
751          }
752    
753        p = pp;  /* Back one character */
754        }        /* End of loop for ANY case */
755    
756      return startptr;  /* Hit start of data */
757      }     /* End of overall switch */
758    }
759    
760    
761    
762    
763    
764    /*************************************************
765  *       Print the previous "after" lines         *  *       Print the previous "after" lines         *
766  *************************************************/  *************************************************/
767    
# Line 495  if (after_context > 0 && lastmatchnumber Line 786  if (after_context > 0 && lastmatchnumber
786    int count = 0;    int count = 0;
787    while (lastmatchrestart < endptr && count++ < after_context)    while (lastmatchrestart < endptr && count++ < after_context)
788      {      {
789        int ellength;
790      char *pp = lastmatchrestart;      char *pp = lastmatchrestart;
791      if (printname != NULL) fprintf(stdout, "%s-", printname);      if (printname != NULL) fprintf(stdout, "%s-", printname);
792      if (number) fprintf(stdout, "%d-", lastmatchnumber++);      if (number) fprintf(stdout, "%d-", lastmatchnumber++);
793      while (*pp != endlinebyte) pp++;      pp = end_of_line(pp, endptr, &ellength);
794      fwrite(lastmatchrestart, 1, pp - lastmatchrestart + (1 + endlineextra),      fwrite(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
795        stdout);      lastmatchrestart = pp;
     lastmatchrestart = pp + 1;  
796      }      }
797    hyphenpending = TRUE;    hyphenpending = TRUE;
798    }    }
# Line 537  int rc = 1; Line 828  int rc = 1;
828  int linenumber = 1;  int linenumber = 1;
829  int lastmatchnumber = 0;  int lastmatchnumber = 0;
830  int count = 0;  int count = 0;
831    int filepos = 0;
832  int offsets[99];  int offsets[99];
833  char *lastmatchrestart = NULL;  char *lastmatchrestart = NULL;
834  char buffer[3*MBUFTHIRD];  char buffer[3*MBUFTHIRD];
# Line 558  way, the buffer is shifted left and re-f Line 850  way, the buffer is shifted left and re-f
850    
851  while (ptr < endptr)  while (ptr < endptr)
852    {    {
853    int i;    int i, endlinelength;
854    int mrc = 0;    int mrc = 0;
855    BOOL match = FALSE;    BOOL match = FALSE;
856      char *matchptr = ptr;
857    char *t = ptr;    char *t = ptr;
858    size_t length, linelength;    size_t length, linelength;
859    
# Line 571  while (ptr < endptr) Line 864  while (ptr < endptr)
864    line. In multiline mode the PCRE_FIRSTLINE option is used for compiling, so    line. In multiline mode the PCRE_FIRSTLINE option is used for compiling, so
865    that any match is constrained to be in the first line. */    that any match is constrained to be in the first line. */
866    
867    linelength = 0;    t = end_of_line(t, endptr, &endlinelength);
868    while (t < endptr && *t++ != endlinebyte) linelength++;    linelength = t - ptr - endlinelength;
869    length = multiline? endptr - ptr : linelength;    length = multiline? (size_t)(endptr - ptr) : linelength;
   
870    
871    /* Extra processing for Jeffrey Friedl's debugging. */    /* Extra processing for Jeffrey Friedl's debugging. */
872    
# Line 624  while (ptr < endptr) Line 916  while (ptr < endptr)
916    }    }
917  #endif  #endif
918    
919      /* We come back here after a match when the -o option (only_matching) is set,
920      in order to find any further matches in the same line. */
921    
922      ONLY_MATCHING_RESTART:
923    
924    /* Run through all the patterns until one matches. Note that we don't include    /* Run through all the patterns until one matches. Note that we don't include
925    the final newline in the subject string. */    the final newline in the subject string. */
926    
927    for (i = 0; i < pattern_count; i++)    for (i = 0; i < pattern_count; i++)
928      {      {
929      mrc = pcre_exec(pattern_list[i], hints_list[i], ptr, length, 0, 0,      mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, length, 0, 0,
930        offsets, 99);        offsets, 99);
931      if (mrc >= 0) { match = TRUE; break; }      if (mrc >= 0) { match = TRUE; break; }
932      if (mrc != PCRE_ERROR_NOMATCH)      if (mrc != PCRE_ERROR_NOMATCH)
# Line 638  while (ptr < endptr) Line 934  while (ptr < endptr)
934        fprintf(stderr, "pcregrep: pcre_exec() error %d while matching ", mrc);        fprintf(stderr, "pcregrep: pcre_exec() error %d while matching ", mrc);
935        if (pattern_count > 1) fprintf(stderr, "pattern number %d to ", i+1);        if (pattern_count > 1) fprintf(stderr, "pattern number %d to ", i+1);
936        fprintf(stderr, "this line:\n");        fprintf(stderr, "this line:\n");
937        fwrite(ptr, 1, linelength, stderr);   /* In case binary zero included */        fwrite(matchptr, 1, linelength, stderr);  /* In case binary zero included */
938        fprintf(stderr, "\n");        fprintf(stderr, "\n");
939        if (error_count == 0 &&        if (error_count == 0 &&
940            (mrc == PCRE_ERROR_MATCHLIMIT || mrc == PCRE_ERROR_RECURSIONLIMIT))            (mrc == PCRE_ERROR_MATCHLIMIT || mrc == PCRE_ERROR_RECURSIONLIMIT))
# Line 685  while (ptr < endptr) Line 981  while (ptr < endptr)
981      else if (quiet) return 0;      else if (quiet) return 0;
982    
983      /* The --only-matching option prints just the substring that matched, and      /* The --only-matching option prints just the substring that matched, and
984      does not pring any context. */      the --file-offsets and --line-offsets options output offsets for the
985        matching substring (they both force --only-matching). None of these options
986        prints any context. Afterwards, adjust the start and length, and then jump
987        back to look for further matches in the same line. If we are in invert
988        mode, however, nothing is printed - this could be still useful because the
989        return code is set. */
990    
991      else if (only_matching)      else if (only_matching)
992        {        {
993        if (printname != NULL) fprintf(stdout, "%s:", printname);        if (!invert)
994        if (number) fprintf(stdout, "%d:", linenumber);          {
995        fwrite(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);          if (printname != NULL) fprintf(stdout, "%s:", printname);
996        fprintf(stdout, "\n");          if (number) fprintf(stdout, "%d:", linenumber);
997            if (line_offsets)
998              fprintf(stdout, "%d,%d", matchptr + offsets[0] - ptr,
999                offsets[1] - offsets[0]);
1000            else if (file_offsets)
1001              fprintf(stdout, "%d,%d", filepos + matchptr + offsets[0] - ptr,
1002                offsets[1] - offsets[0]);
1003            else
1004              fwrite(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
1005            fprintf(stdout, "\n");
1006            matchptr += offsets[1];
1007            length -= offsets[1];
1008            match = FALSE;
1009            goto ONLY_MATCHING_RESTART;
1010            }
1011        }        }
1012    
1013      /* 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 706  while (ptr < endptr) Line 1021  while (ptr < endptr)
1021    
1022        if (after_context > 0 && lastmatchnumber > 0)        if (after_context > 0 && lastmatchnumber > 0)
1023          {          {
1024            int ellength;
1025          int linecount = 0;          int linecount = 0;
1026          char *p = lastmatchrestart;          char *p = lastmatchrestart;
1027    
1028          while (p < ptr && linecount < after_context)          while (p < ptr && linecount < after_context)
1029            {            {
1030            while (*p != endlinebyte) p++;            p = end_of_line(p, ptr, &ellength);
           p++;  
1031            linecount++;            linecount++;
1032            }            }
1033    
# Line 725  while (ptr < endptr) Line 1040  while (ptr < endptr)
1040            char *pp = lastmatchrestart;            char *pp = lastmatchrestart;
1041            if (printname != NULL) fprintf(stdout, "%s-", printname);            if (printname != NULL) fprintf(stdout, "%s-", printname);
1042            if (number) fprintf(stdout, "%d-", lastmatchnumber++);            if (number) fprintf(stdout, "%d-", lastmatchnumber++);
1043            while (*pp != endlinebyte) pp++;            pp = end_of_line(pp, endptr, &ellength);
1044            fwrite(lastmatchrestart, 1, pp - lastmatchrestart +            fwrite(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
1045              (1 + endlineextra), stdout);            lastmatchrestart = pp;
           lastmatchrestart = pp + 1;  
1046            }            }
1047          if (lastmatchrestart != ptr) hyphenpending = TRUE;          if (lastmatchrestart != ptr) hyphenpending = TRUE;
1048          }          }
# Line 754  while (ptr < endptr) Line 1068  while (ptr < endptr)
1068                 linecount < before_context)                 linecount < before_context)
1069            {            {
1070            linecount++;            linecount++;
1071            p--;            p = previous_line(p, buffer);
           while (p > buffer && p[-1] != endlinebyte) p--;  
1072            }            }
1073    
1074          if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted)          if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted)
# Line 763  while (ptr < endptr) Line 1076  while (ptr < endptr)
1076    
1077          while (p < ptr)          while (p < ptr)
1078            {            {
1079              int ellength;
1080            char *pp = p;            char *pp = p;
1081            if (printname != NULL) fprintf(stdout, "%s-", printname);            if (printname != NULL) fprintf(stdout, "%s-", printname);
1082            if (number) fprintf(stdout, "%d-", linenumber - linecount--);            if (number) fprintf(stdout, "%d-", linenumber - linecount--);
1083            while (*pp != endlinebyte) pp++;            pp = end_of_line(pp, endptr, &ellength);
1084            fwrite(p, 1, pp - p + (1 + endlineextra), stdout);            fwrite(p, 1, pp - p, stdout);
1085            p = pp + 1;            p = pp;
1086            }            }
1087          }          }
1088    
# Line 783  while (ptr < endptr) Line 1097  while (ptr < endptr)
1097    
1098        /* In multiline mode, we want to print to the end of the line in which        /* In multiline mode, we want to print to the end of the line in which
1099        the end of the matched string is found, so we adjust linelength and the        the end of the matched string is found, so we adjust linelength and the
1100        line number appropriately. Because the PCRE_FIRSTLINE option is set, the        line number appropriately, but only when there actually was a match
1101        start of the match will always be before the first newline sequence. */        (invert not set). Because the PCRE_FIRSTLINE option is set, the start of
1102          the match will always be before the first newline sequence. */
1103    
1104        if (multiline)        if (multiline)
1105          {          {
1106          char *endmatch = ptr + offsets[1];          int ellength;
1107          t = ptr;          char *endmatch = ptr;
1108          while (t < endmatch) { if (*t++ == endlinebyte) linenumber++; }          if (!invert)
1109          while (endmatch < endptr && *endmatch != endlinebyte) endmatch++;            {
1110          linelength = endmatch - ptr;            endmatch += offsets[1];
1111              t = ptr;
1112              while (t < endmatch)
1113                {
1114                t = end_of_line(t, endptr, &ellength);
1115                if (t <= endmatch) linenumber++; else break;
1116                }
1117              }
1118            endmatch = end_of_line(endmatch, endptr, &ellength);
1119            linelength = endmatch - ptr - ellength;
1120          }          }
1121    
1122        /*** NOTE: Use only fwrite() to output the data line, so that binary        /*** NOTE: Use only fwrite() to output the data line, so that binary
# Line 822  while (ptr < endptr) Line 1146  while (ptr < endptr)
1146          fprintf(stdout, "%c[%sm", 0x1b, colour_string);          fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1147          fwrite(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);          fwrite(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
1148          fprintf(stdout, "%c[00m", 0x1b);          fprintf(stdout, "%c[00m", 0x1b);
1149          fwrite(ptr + offsets[1], 1, linelength - offsets[1], stdout);          fwrite(ptr + offsets[1], 1, (linelength + endlinelength) - offsets[1],
1150              stdout);
1151          }          }
1152        else fwrite(ptr, 1, linelength, stdout);        else fwrite(ptr, 1, linelength + endlinelength, stdout);
   
       fprintf(stdout, "\n");  
1153        }        }
1154    
1155      /* End of doing what has to be done for a match */      /* End of doing what has to be done for a match */
# Line 836  while (ptr < endptr) Line 1159  while (ptr < endptr)
1159      /* Remember where the last match happened for after_context. We remember      /* Remember where the last match happened for after_context. We remember
1160      where we are about to restart, and that line's number. */      where we are about to restart, and that line's number. */
1161    
1162      lastmatchrestart = ptr + linelength + 1;      lastmatchrestart = ptr + linelength + endlinelength;
1163      lastmatchnumber = linenumber + 1;      lastmatchnumber = linenumber + 1;
1164      }      }
1165    
1166    /* Advance to after the newline and increment the line number. */    /* For a match in multiline inverted mode (which of course did not cause
1167      anything to be printed), we have to move on to the end of the match before
1168      proceeding. */
1169    
1170      if (multiline && invert && match)
1171        {
1172        int ellength;
1173        char *endmatch = ptr + offsets[1];
1174        t = ptr;
1175        while (t < endmatch)
1176          {
1177          t = end_of_line(t, endptr, &ellength);
1178          if (t <= endmatch) linenumber++; else break;
1179          }
1180        endmatch = end_of_line(endmatch, endptr, &ellength);
1181        linelength = endmatch - ptr - ellength;
1182        }
1183    
1184      /* Advance to after the newline and increment the line number. The file
1185      offset to the current line is maintained in filepos. */
1186    
1187    ptr += linelength + 1;    ptr += linelength + endlinelength;
1188      filepos += linelength + endlinelength;
1189    linenumber++;    linenumber++;
1190    
1191    /* If we haven't yet reached the end of the file (the buffer is full), and    /* If we haven't yet reached the end of the file (the buffer is full), and
# Line 1029  for (op = optionlist; op->one_char != 0; Line 1372  for (op = optionlist; op->one_char != 0;
1372    if (op->one_char > 0) fprintf(stderr, "%c", op->one_char);    if (op->one_char > 0) fprintf(stderr, "%c", op->one_char);
1373    }    }
1374  fprintf(stderr, "] [long options] [pattern] [files]\n");  fprintf(stderr, "] [long options] [pattern] [files]\n");
1375  fprintf(stderr, "Type `pcregrep --help' for more information.\n");  fprintf(stderr, "Type `pcregrep --help' for more information and the long "
1376      "options.\n");
1377  return rc;  return rc;
1378  }  }
1379    
# Line 1084  handle_option(int letter, int options) Line 1428  handle_option(int letter, int options)
1428  {  {
1429  switch(letter)  switch(letter)
1430    {    {
1431      case N_FOFFSETS: file_offsets = TRUE; break;
1432    case N_HELP: help(); exit(0);    case N_HELP: help(); exit(0);
1433      case N_LOFFSETS: line_offsets = number = TRUE; break;
1434    case 'c': count_only = TRUE; break;    case 'c': count_only = TRUE; break;
1435    case 'F': process_options |= PO_FIXED_STRINGS; break;    case 'F': process_options |= PO_FIXED_STRINGS; break;
1436    case 'H': filenames = FN_FORCE; break;    case 'H': filenames = FN_FORCE; break;
# Line 1098  switch(letter) Line 1444  switch(letter)
1444    case 'q': quiet = TRUE; break;    case 'q': quiet = TRUE; break;
1445    case 'r': dee_action = dee_RECURSE; break;    case 'r': dee_action = dee_RECURSE; break;
1446    case 's': silent = TRUE; break;    case 's': silent = TRUE; break;
1447    case 'u': options |= PCRE_UTF8; break;    case 'u': options |= PCRE_UTF8; utf8 = TRUE; break;
1448    case 'v': invert = TRUE; break;    case 'v': invert = TRUE; break;
1449    case 'w': process_options |= PO_WORD_MATCH; break;    case 'w': process_options |= PO_WORD_MATCH; break;
1450    case 'x': process_options |= PO_LINE_MATCH; break;    case 'x': process_options |= PO_LINE_MATCH; break;
1451    
1452    case 'V':    case 'V':
1453    fprintf(stderr, "pcregrep version %s using ", VERSION);    fprintf(stderr, "pcregrep version %s\n", pcre_version());
   fprintf(stderr, "PCRE version %s\n", pcre_version());  
1454    exit(0);    exit(0);
1455    break;    break;
1456    
# Line 1181  sprintf(buffer, "%s%.*s%s", prefix[proce Line 1526  sprintf(buffer, "%s%.*s%s", prefix[proce
1526    suffix[process_options]);    suffix[process_options]);
1527  pattern_list[pattern_count] =  pattern_list[pattern_count] =
1528    pcre_compile(buffer, options, &error, &errptr, pcretables);    pcre_compile(buffer, options, &error, &errptr, pcretables);
1529  if (pattern_list[pattern_count++] != NULL) return TRUE;  if (pattern_list[pattern_count] != NULL)
1530      {
1531      pattern_count++;
1532      return TRUE;
1533      }
1534    
1535  /* Handle compile errors */  /* Handle compile errors */
1536    
# Line 1231  compile_pattern(char *pattern, int optio Line 1580  compile_pattern(char *pattern, int optio
1580  {  {
1581  if ((process_options & PO_FIXED_STRINGS) != 0)  if ((process_options & PO_FIXED_STRINGS) != 0)
1582    {    {
1583      char *eop = pattern + strlen(pattern);
1584    char buffer[MBUFTHIRD];    char buffer[MBUFTHIRD];
1585    for(;;)    for(;;)
1586      {      {
1587      char *p = strchr(pattern, endlinebyte);      int ellength;
1588      if (p == NULL)      char *p = end_of_line(pattern, eop, &ellength);
1589        if (ellength == 0)
1590        return compile_single_pattern(pattern, options, filename, count);        return compile_single_pattern(pattern, options, filename, count);
1591      sprintf(buffer, "%.*s", p - pattern - endlineextra, pattern);      sprintf(buffer, "%.*s", (int)(p - pattern - ellength), pattern);
1592      pattern = p + 1;      pattern = p;
1593      if (!compile_single_pattern(buffer, options, filename, count))      if (!compile_single_pattern(buffer, options, filename, count))
1594        return FALSE;        return FALSE;
1595      }      }
# Line 1261  int i, j; Line 1612  int i, j;
1612  int rc = 1;  int rc = 1;
1613  int pcre_options = 0;  int pcre_options = 0;
1614  int cmd_pattern_count = 0;  int cmd_pattern_count = 0;
1615    int hint_count = 0;
1616  int errptr;  int errptr;
1617  BOOL only_one_at_top;  BOOL only_one_at_top;
1618  char *patterns[MAX_PATTERN_COUNT];  char *patterns[MAX_PATTERN_COUNT];
1619  const char *locale_from = "--locale";  const char *locale_from = "--locale";
1620  const char *error;  const char *error;
1621    
1622  /* 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;
1623    "lf", "cr", "crlf", and "any" are supported. Anything else is treated as "lf".
1624    */
1625    
1626  (void)pcre_config(PCRE_CONFIG_NEWLINE, &i);  (void)pcre_config(PCRE_CONFIG_NEWLINE, &i);
1627  switch(i)  switch(i)
# Line 1275  switch(i) Line 1629  switch(i)
1629    default:                 newline = (char *)"lf"; break;    default:                 newline = (char *)"lf"; break;
1630    case '\r':               newline = (char *)"cr"; break;    case '\r':               newline = (char *)"cr"; break;
1631    case ('\r' << 8) | '\n': newline = (char *)"crlf"; break;    case ('\r' << 8) | '\n': newline = (char *)"crlf"; break;
1632      case -1:                 newline = (char *)"any"; break;
1633      case -2:                 newline = (char *)"anycrlf"; break;
1634    }    }
1635    
1636  /* Process the options */  /* Process the options */
# Line 1332  for (i = 1; i < argc; i++) Line 1688  for (i = 1; i < argc; i++)
1688          else                 /* Special case xxx=data */          else                 /* Special case xxx=data */
1689            {            {
1690            int oplen = equals - op->long_name;            int oplen = equals - op->long_name;
1691            int arglen = (argequals == NULL)? strlen(arg) : argequals - arg;            int arglen = (argequals == NULL)? (int)strlen(arg) : argequals - arg;
1692            if (oplen == arglen && strncmp(arg, op->long_name, oplen) == 0)            if (oplen == arglen && strncmp(arg, op->long_name, oplen) == 0)
1693              {              {
1694              option_data = arg + arglen;              option_data = arg + arglen;
# Line 1351  for (i = 1; i < argc; i++) Line 1707  for (i = 1; i < argc; i++)
1707          char buff2[24];          char buff2[24];
1708          int baselen = opbra - op->long_name;          int baselen = opbra - op->long_name;
1709          sprintf(buff1, "%.*s", baselen, op->long_name);          sprintf(buff1, "%.*s", baselen, op->long_name);
1710          sprintf(buff2, "%s%.*s", buff1, strlen(op->long_name) - baselen - 2,          sprintf(buff2, "%s%.*s", buff1,
1711            opbra + 1);            (int)strlen(op->long_name) - baselen - 2, opbra + 1);
1712          if (strcmp(arg, buff1) == 0 || strcmp(arg, buff2) == 0)          if (strcmp(arg, buff1) == 0 || strcmp(arg, buff2) == 0)
1713            break;            break;
1714          }          }
# Line 1510  if (both_context > 0) Line 1866  if (both_context > 0)
1866    if (after_context == 0) after_context = both_context;    if (after_context == 0) after_context = both_context;
1867    if (before_context == 0) before_context = both_context;    if (before_context == 0) before_context = both_context;
1868    }    }
1869    
1870    /* Only one of --only-matching, --file-offsets, or --line-offsets is permitted.
1871    However, the latter two set the only_matching flag. */
1872    
1873    if ((only_matching && (file_offsets || line_offsets)) ||
1874        (file_offsets && line_offsets))
1875      {
1876      fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets "
1877        "and/or --line-offsets\n");
1878      exit(usage(2));
1879      }
1880    
1881    if (file_offsets || line_offsets) only_matching = TRUE;
1882    
1883  /* 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
1884  LC_ALL environment variable is set, and if so, use it. */  LC_ALL environment variable is set, and if so, use it. */
# Line 1565  if (colour_option != NULL && strcmp(colo Line 1934  if (colour_option != NULL && strcmp(colo
1934  if (strcmp(newline, "cr") == 0 || strcmp(newline, "CR") == 0)  if (strcmp(newline, "cr") == 0 || strcmp(newline, "CR") == 0)
1935    {    {
1936    pcre_options |= PCRE_NEWLINE_CR;    pcre_options |= PCRE_NEWLINE_CR;
1937    endlinebyte = '\r';    endlinetype = EL_CR;
1938    }    }
1939  else if (strcmp(newline, "lf") == 0 || strcmp(newline, "LF") == 0)  else if (strcmp(newline, "lf") == 0 || strcmp(newline, "LF") == 0)
1940    {    {
1941    pcre_options |= PCRE_NEWLINE_LF;    pcre_options |= PCRE_NEWLINE_LF;
1942      endlinetype = EL_LF;
1943    }    }
1944  else if (strcmp(newline, "crlf") == 0 || strcmp(newline, "CRLF") == 0)  else if (strcmp(newline, "crlf") == 0 || strcmp(newline, "CRLF") == 0)
1945    {    {
1946    pcre_options |= PCRE_NEWLINE_CRLF;    pcre_options |= PCRE_NEWLINE_CRLF;
1947    endlineextra = 1;    endlinetype = EL_CRLF;
1948      }
1949    else if (strcmp(newline, "any") == 0 || strcmp(newline, "ANY") == 0)
1950      {
1951      pcre_options |= PCRE_NEWLINE_ANY;
1952      endlinetype = EL_ANY;
1953      }
1954    else if (strcmp(newline, "anycrlf") == 0 || strcmp(newline, "ANYCRLF") == 0)
1955      {
1956      pcre_options |= PCRE_NEWLINE_ANYCRLF;
1957      endlinetype = EL_ANYCRLF;
1958    }    }
1959  else  else
1960    {    {
# Line 1630  hints_list = (pcre_extra **)malloc(MAX_P Line 2010  hints_list = (pcre_extra **)malloc(MAX_P
2010  if (pattern_list == NULL || hints_list == NULL)  if (pattern_list == NULL || hints_list == NULL)
2011    {    {
2012    fprintf(stderr, "pcregrep: malloc failed\n");    fprintf(stderr, "pcregrep: malloc failed\n");
2013    return 2;    goto EXIT2;
2014    }    }
2015    
2016  /* If no patterns were provided by -e, and there is no file provided by -f,  /* If no patterns were provided by -e, and there is no file provided by -f,
# Line 1649  for (j = 0; j < cmd_pattern_count; j++) Line 2029  for (j = 0; j < cmd_pattern_count; j++)
2029    {    {
2030    if (!compile_pattern(patterns[j], pcre_options, NULL,    if (!compile_pattern(patterns[j], pcre_options, NULL,
2031         (j == 0 && cmd_pattern_count == 1)? 0 : j + 1))         (j == 0 && cmd_pattern_count == 1)? 0 : j + 1))
2032      return 2;      goto EXIT2;
2033    }    }
2034    
2035  /* Compile the regular expressions that are provided in a file. */  /* Compile the regular expressions that are provided in a file. */
# Line 1673  if (pattern_filename != NULL) Line 2053  if (pattern_filename != NULL)
2053        {        {
2054        fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pattern_filename,        fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pattern_filename,
2055          strerror(errno));          strerror(errno));
2056        return 2;        goto EXIT2;
2057        }        }
2058      filename = pattern_filename;      filename = pattern_filename;
2059      }      }
# Line 1686  if (pattern_filename != NULL) Line 2066  if (pattern_filename != NULL)
2066      linenumber++;      linenumber++;
2067      if (buffer[0] == 0) continue;   /* Skip blank lines */      if (buffer[0] == 0) continue;   /* Skip blank lines */
2068      if (!compile_pattern(buffer, pcre_options, filename, linenumber))      if (!compile_pattern(buffer, pcre_options, filename, linenumber))
2069        return 2;        goto EXIT2;
2070      }      }
2071    
2072    if (f != stdin) fclose(f);    if (f != stdin) fclose(f);
# Line 1702  for (j = 0; j < pattern_count; j++) Line 2082  for (j = 0; j < pattern_count; j++)
2082      char s[16];      char s[16];
2083      if (pattern_count == 1) s[0] = 0; else sprintf(s, " number %d", j);      if (pattern_count == 1) s[0] = 0; else sprintf(s, " number %d", j);
2084      fprintf(stderr, "pcregrep: Error while studying regex%s: %s\n", s, error);      fprintf(stderr, "pcregrep: Error while studying regex%s: %s\n", s, error);
2085      return 2;      goto EXIT2;
2086      }      }
2087      hint_count++;
2088    }    }
2089    
2090  /* If there are include or exclude patterns, compile them. */  /* If there are include or exclude patterns, compile them. */
# Line 1716  if (exclude_pattern != NULL) Line 2097  if (exclude_pattern != NULL)
2097      {      {
2098      fprintf(stderr, "pcregrep: Error in 'exclude' regex at offset %d: %s\n",      fprintf(stderr, "pcregrep: Error in 'exclude' regex at offset %d: %s\n",
2099        errptr, error);        errptr, error);
2100      return 2;      goto EXIT2;
2101      }      }
2102    }    }
2103    
# Line 1728  if (include_pattern != NULL) Line 2109  if (include_pattern != NULL)
2109      {      {
2110      fprintf(stderr, "pcregrep: Error in 'include' regex at offset %d: %s\n",      fprintf(stderr, "pcregrep: Error in 'include' regex at offset %d: %s\n",
2111        errptr, error);        errptr, error);
2112      return 2;      goto EXIT2;
2113      }      }
2114    }    }
2115    
2116  /* 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. */
2117    
2118  if (i >= argc)  if (i >= argc)
2119    return pcregrep(stdin, (filenames > FN_DEFAULT)? stdin_name : NULL);    {
2120      rc = pcregrep(stdin, (filenames > FN_DEFAULT)? stdin_name : NULL);
2121      goto EXIT;
2122      }
2123    
2124  /* Otherwise, work through the remaining arguments as files or directories.  /* Otherwise, work through the remaining arguments as files or directories.
2125  Pass in the fact that there is only one argument at top level - this suppresses  Pass in the fact that there is only one argument at top level - this suppresses
# Line 1752  for (; i < argc; i++) Line 2136  for (; i < argc; i++)
2136      else if (frc == 0 && rc == 1) rc = 0;      else if (frc == 0 && rc == 1) rc = 0;
2137    }    }
2138    
2139    EXIT:
2140    if (pattern_list != NULL)
2141      {
2142      for (i = 0; i < pattern_count; i++) free(pattern_list[i]);
2143      free(pattern_list);
2144      }
2145    if (hints_list != NULL)
2146      {
2147      for (i = 0; i < hint_count; i++) free(hints_list[i]);
2148      free(hints_list);
2149      }
2150  return rc;  return rc;
2151    
2152    EXIT2:
2153    rc = 2;
2154    goto EXIT;
2155  }  }
2156    
2157  /* End of pcregrep */  /* End of pcregrep */

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

  ViewVC Help
Powered by ViewVC 1.1.5