/[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

code/trunk/pcregrep.c revision 286 by ph10, Mon Dec 17 14:46:11 2007 UTC code/tags/pcre-8.01/pcregrep.c revision 490 by ph10, Tue Jan 19 16:45:59 2010 UTC
# Line 6  Line 6 
6  its pattern matching. On a Unix or Win32 system it can recurse into  its pattern matching. On a Unix or Win32 system it can recurse into
7  directories.  directories.
8    
9             Copyright (c) 1997-2007 University of Cambridge             Copyright (c) 1997-2009 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 71  POSSIBILITY OF SUCH DAMAGE. Line 71  POSSIBILITY OF SUCH DAMAGE.
71  typedef int BOOL;  typedef int BOOL;
72    
73  #define MAX_PATTERN_COUNT 100  #define MAX_PATTERN_COUNT 100
74    #define OFFSET_SIZE 99
75    
76  #if BUFSIZ > 8192  #if BUFSIZ > 8192
77  #define MBUFTHIRD BUFSIZ  #define MBUFTHIRD BUFSIZ
# Line 82  typedef int BOOL; Line 83  typedef int BOOL;
83  output. The order is important; it is assumed that a file name is wanted for  output. The order is important; it is assumed that a file name is wanted for
84  all values greater than FN_DEFAULT. */  all values greater than FN_DEFAULT. */
85    
86  enum { FN_NONE, FN_DEFAULT, FN_ONLY, FN_NOMATCH_ONLY, FN_FORCE };  enum { FN_NONE, FN_DEFAULT, FN_MATCH_ONLY, FN_NOMATCH_ONLY, FN_FORCE };
87    
88  /* File reading styles */  /* File reading styles */
89    
# Line 139  static pcre_extra **hints_list = NULL; Line 140  static pcre_extra **hints_list = NULL;
140    
141  static char *include_pattern = NULL;  static char *include_pattern = NULL;
142  static char *exclude_pattern = NULL;  static char *exclude_pattern = NULL;
143    static char *include_dir_pattern = NULL;
144    static char *exclude_dir_pattern = NULL;
145    
146  static pcre *include_compiled = NULL;  static pcre *include_compiled = NULL;
147  static pcre *exclude_compiled = NULL;  static pcre *exclude_compiled = NULL;
148    static pcre *include_dir_compiled = NULL;
149    static pcre *exclude_dir_compiled = NULL;
150    
151  static int after_context = 0;  static int after_context = 0;
152  static int before_context = 0;  static int before_context = 0;
# Line 160  static BOOL invert = FALSE; Line 165  static BOOL invert = FALSE;
165  static BOOL line_offsets = FALSE;  static BOOL line_offsets = FALSE;
166  static BOOL multiline = FALSE;  static BOOL multiline = FALSE;
167  static BOOL number = FALSE;  static BOOL number = FALSE;
168    static BOOL omit_zero_count = FALSE;
169  static BOOL only_matching = FALSE;  static BOOL only_matching = FALSE;
170  static BOOL quiet = FALSE;  static BOOL quiet = FALSE;
171  static BOOL silent = FALSE;  static BOOL silent = FALSE;
# Line 181  typedef struct option_item { Line 187  typedef struct option_item {
187  /* Options without a single-letter equivalent get a negative value. This can be  /* Options without a single-letter equivalent get a negative value. This can be
188  used to identify them. */  used to identify them. */
189    
190  #define N_COLOUR    (-1)  #define N_COLOUR       (-1)
191  #define N_EXCLUDE   (-2)  #define N_EXCLUDE      (-2)
192  #define N_HELP      (-3)  #define N_EXCLUDE_DIR  (-3)
193  #define N_INCLUDE   (-4)  #define N_HELP         (-4)
194  #define N_LABEL     (-5)  #define N_INCLUDE      (-5)
195  #define N_LOCALE    (-6)  #define N_INCLUDE_DIR  (-6)
196  #define N_NULL      (-7)  #define N_LABEL        (-7)
197  #define N_LOFFSETS  (-8)  #define N_LOCALE       (-8)
198  #define N_FOFFSETS  (-9)  #define N_NULL         (-9)
199    #define N_LOFFSETS     (-10)
200    #define N_FOFFSETS     (-11)
201    
202  static option_item optionlist[] = {  static option_item optionlist[] = {
203    { OP_NODATA,    N_NULL,   NULL,              "",              "  terminate options" },    { OP_NODATA,    N_NULL,   NULL,              "",              "  terminate options" },
# Line 202  static option_item optionlist[] = { Line 210  static option_item optionlist[] = {
210    { OP_OP_STRING, N_COLOUR, &colour_option,    "colour=option", "matched text colour option" },    { OP_OP_STRING, N_COLOUR, &colour_option,    "colour=option", "matched text colour option" },
211    { OP_STRING,    'D',      &DEE_option,       "devices=action","how to handle devices, FIFOs, and sockets" },    { OP_STRING,    'D',      &DEE_option,       "devices=action","how to handle devices, FIFOs, and sockets" },
212    { OP_STRING,    'd',      &dee_option,       "directories=action", "how to handle directories" },    { OP_STRING,    'd',      &dee_option,       "directories=action", "how to handle directories" },
213    { OP_PATLIST,   'e',      NULL,              "regex(p)",      "specify pattern (may be used more than once)" },    { OP_PATLIST,   'e',      NULL,              "regex(p)=pattern", "specify pattern (may be used more than once)" },
214    { 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" },
215    { OP_STRING,    'f',      &pattern_filename, "file=path",     "read patterns from file" },    { OP_STRING,    'f',      &pattern_filename, "file=path",     "read patterns from file" },
216    { OP_NODATA,    N_FOFFSETS, NULL,            "file-offsets",  "output file offsets, not text" },    { OP_NODATA,    N_FOFFSETS, NULL,            "file-offsets",  "output file offsets, not text" },
217    { OP_NODATA,    'H',      NULL,              "with-filename", "force the prefixing filename on output" },    { OP_NODATA,    'H',      NULL,              "with-filename", "force the prefixing filename on output" },
# Line 222  static option_item optionlist[] = { Line 230  static option_item optionlist[] = {
230    { OP_NODATA,    'r',      NULL,              "recursive",     "recursively scan sub-directories" },    { OP_NODATA,    'r',      NULL,              "recursive",     "recursively scan sub-directories" },
231    { OP_STRING,    N_EXCLUDE,&exclude_pattern,  "exclude=pattern","exclude matching files when recursing" },    { OP_STRING,    N_EXCLUDE,&exclude_pattern,  "exclude=pattern","exclude matching files when recursing" },
232    { OP_STRING,    N_INCLUDE,&include_pattern,  "include=pattern","include matching files when recursing" },    { OP_STRING,    N_INCLUDE,&include_pattern,  "include=pattern","include matching files when recursing" },
233      { OP_STRING,    N_EXCLUDE_DIR,&exclude_dir_pattern, "exclude_dir=pattern","exclude matching directories when recursing" },
234      { OP_STRING,    N_INCLUDE_DIR,&include_dir_pattern, "include_dir=pattern","include matching directories when recursing" },
235  #ifdef JFRIEDL_DEBUG  #ifdef JFRIEDL_DEBUG
236    { OP_OP_NUMBER, 'S',      &S_arg,            "jeffS",         "replace matched (sub)string with X" },    { OP_OP_NUMBER, 'S',      &S_arg,            "jeffS",         "replace matched (sub)string with X" },
237  #endif  #endif
# Line 813  if (after_context > 0 && lastmatchnumber Line 823  if (after_context > 0 && lastmatchnumber
823    
824    
825  /*************************************************  /*************************************************
826    *   Apply patterns to subject till one matches   *
827    *************************************************/
828    
829    /* This function is called to run through all patterns, looking for a match. It
830    is used multiple times for the same subject when colouring is enabled, in order
831    to find all possible matches.
832    
833    Arguments:
834      matchptr    the start of the subject
835      length      the length of the subject to match
836      offsets     the offets vector to fill in
837      mrc         address of where to put the result of pcre_exec()
838    
839    Returns:      TRUE if there was a match
840                  FALSE if there was no match
841                  invert if there was a non-fatal error
842    */
843    
844    static BOOL
845    match_patterns(char *matchptr, size_t length, int *offsets, int *mrc)
846    {
847    int i;
848    for (i = 0; i < pattern_count; i++)
849      {
850      *mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, length, 0,
851        PCRE_NOTEMPTY, offsets, OFFSET_SIZE);
852      if (*mrc >= 0) return TRUE;
853      if (*mrc == PCRE_ERROR_NOMATCH) continue;
854      fprintf(stderr, "pcregrep: pcre_exec() error %d while matching ", *mrc);
855      if (pattern_count > 1) fprintf(stderr, "pattern number %d to ", i+1);
856      fprintf(stderr, "this text:\n");
857      fwrite(matchptr, 1, length, stderr);  /* In case binary zero included */
858      fprintf(stderr, "\n");
859      if (error_count == 0 &&
860          (*mrc == PCRE_ERROR_MATCHLIMIT || *mrc == PCRE_ERROR_RECURSIONLIMIT))
861        {
862        fprintf(stderr, "pcregrep: error %d means that a resource limit "
863          "was exceeded\n", *mrc);
864        fprintf(stderr, "pcregrep: check your regex for nested unlimited loops\n");
865        }
866      if (error_count++ > 20)
867        {
868        fprintf(stderr, "pcregrep: too many errors - abandoned\n");
869        exit(2);
870        }
871      return invert;    /* No more matching; don't show the line again */
872      }
873    
874    return FALSE;  /* No match, no errors */
875    }
876    
877    
878    
879    /*************************************************
880  *            Grep an individual file             *  *            Grep an individual file             *
881  *************************************************/  *************************************************/
882    
# Line 845  int linenumber = 1; Line 909  int linenumber = 1;
909  int lastmatchnumber = 0;  int lastmatchnumber = 0;
910  int count = 0;  int count = 0;
911  int filepos = 0;  int filepos = 0;
912  int offsets[99];  int offsets[OFFSET_SIZE];
913  char *lastmatchrestart = NULL;  char *lastmatchrestart = NULL;
914  char buffer[3*MBUFTHIRD];  char buffer[3*MBUFTHIRD];
915  char *ptr = buffer;  char *ptr = buffer;
# Line 901  way, the buffer is shifted left and re-f Line 965  way, the buffer is shifted left and re-f
965    
966  while (ptr < endptr)  while (ptr < endptr)
967    {    {
968    int i, endlinelength;    int endlinelength;
969    int mrc = 0;    int mrc = 0;
970    BOOL match = FALSE;    BOOL match;
971    char *matchptr = ptr;    char *matchptr = ptr;
972    char *t = ptr;    char *t = ptr;
973    size_t length, linelength;    size_t length, linelength;
# Line 911  while (ptr < endptr) Line 975  while (ptr < endptr)
975    /* At this point, ptr is at the start of a line. We need to find the length    /* At this point, ptr is at the start of a line. We need to find the length
976    of the subject string to pass to pcre_exec(). In multiline mode, it is the    of the subject string to pass to pcre_exec(). In multiline mode, it is the
977    length remainder of the data in the buffer. Otherwise, it is the length of    length remainder of the data in the buffer. Otherwise, it is the length of
978    the next line. After matching, we always advance by the length of the next    the next line, excluding the terminating newline. After matching, we always
979    line. In multiline mode the PCRE_FIRSTLINE option is used for compiling, so    advance by the length of the next line. In multiline mode the PCRE_FIRSTLINE
980    that any match is constrained to be in the first line. */    option is used for compiling, so that any match is constrained to be in the
981      first line. */
982    
983    t = end_of_line(t, endptr, &endlinelength);    t = end_of_line(t, endptr, &endlinelength);
984    linelength = t - ptr - endlinelength;    linelength = t - ptr - endlinelength;
# Line 928  while (ptr < endptr) Line 993  while (ptr < endptr)
993        #include <time.h>        #include <time.h>
994        struct timeval start_time, end_time;        struct timeval start_time, end_time;
995        struct timezone dummy;        struct timezone dummy;
996          int i;
997    
998        if (jfriedl_XT)        if (jfriedl_XT)
999        {        {
# Line 953  while (ptr < endptr) Line 1019  while (ptr < endptr)
1019    
1020    
1021        for (i = 0; i < jfriedl_XR; i++)        for (i = 0; i < jfriedl_XR; i++)
1022            match = (pcre_exec(pattern_list[0], hints_list[0], ptr, length, 0, 0, offsets, 99) >= 0);            match = (pcre_exec(pattern_list[0], hints_list[0], ptr, length, 0,
1023                  PCRE_NOTEMPTY, offsets, OFFSET_SIZE) >= 0);
1024    
1025        if (gettimeofday(&end_time, &dummy) != 0)        if (gettimeofday(&end_time, &dummy) != 0)
1026                perror("bad gettimeofday");                perror("bad gettimeofday");
# Line 972  while (ptr < endptr) Line 1039  while (ptr < endptr)
1039    
1040    ONLY_MATCHING_RESTART:    ONLY_MATCHING_RESTART:
1041    
1042    /* Run through all the patterns until one matches. Note that we don't include    /* Run through all the patterns until one matches or there is an error other
1043    the final newline in the subject string. */    than NOMATCH. This code is in a subroutine so that it can be re-used for
1044      finding subsequent matches when colouring matched lines. */
1045    
1046    for (i = 0; i < pattern_count; i++)    match = match_patterns(matchptr, length, offsets, &mrc);
     {  
     mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, length, 0, 0,  
       offsets, 99);  
     if (mrc >= 0) { match = TRUE; break; }  
     if (mrc != PCRE_ERROR_NOMATCH)  
       {  
       fprintf(stderr, "pcregrep: pcre_exec() error %d while matching ", mrc);  
       if (pattern_count > 1) fprintf(stderr, "pattern number %d to ", i+1);  
       fprintf(stderr, "this line:\n");  
       fwrite(matchptr, 1, linelength, stderr);  /* In case binary zero included */  
       fprintf(stderr, "\n");  
       if (error_count == 0 &&  
           (mrc == PCRE_ERROR_MATCHLIMIT || mrc == PCRE_ERROR_RECURSIONLIMIT))  
         {  
         fprintf(stderr, "pcregrep: error %d means that a resource limit "  
           "was exceeded\n", mrc);  
         fprintf(stderr, "pcregrep: check your regex for nested unlimited loops\n");  
         }  
       if (error_count++ > 20)  
         {  
         fprintf(stderr, "pcregrep: too many errors - abandoned\n");  
         exit(2);  
         }  
       match = invert;    /* No more matching; don't show the line again */  
       break;  
       }  
     }  
1047    
1048    /* 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. */
1049    
# Line 1021  while (ptr < endptr) Line 1062  while (ptr < endptr)
1062      /* If all we want is a file name, there is no need to scan any more lines      /* If all we want is a file name, there is no need to scan any more lines
1063      in the file. */      in the file. */
1064    
1065      else if (filenames == FN_ONLY)      else if (filenames == FN_MATCH_ONLY)
1066        {        {
1067        fprintf(stdout, "%s\n", printname);        fprintf(stdout, "%s\n", printname);
1068        return 0;        return 0;
# Line 1046  while (ptr < endptr) Line 1087  while (ptr < endptr)
1087          if (printname != NULL) fprintf(stdout, "%s:", printname);          if (printname != NULL) fprintf(stdout, "%s:", printname);
1088          if (number) fprintf(stdout, "%d:", linenumber);          if (number) fprintf(stdout, "%d:", linenumber);
1089          if (line_offsets)          if (line_offsets)
1090            fprintf(stdout, "%d,%d", matchptr + offsets[0] - ptr,            fprintf(stdout, "%d,%d", (int)(matchptr + offsets[0] - ptr),
1091              offsets[1] - offsets[0]);              offsets[1] - offsets[0]);
1092          else if (file_offsets)          else if (file_offsets)
1093            fprintf(stdout, "%d,%d", filepos + matchptr + offsets[0] - ptr,            fprintf(stdout, "%d,%d", (int)(filepos + matchptr + offsets[0] - ptr),
1094              offsets[1] - offsets[0]);              offsets[1] - offsets[0]);
1095          else          else
1096              {
1097              if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1098            fwrite(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);            fwrite(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
1099              if (do_colour) fprintf(stdout, "%c[00m", 0x1b);
1100              }
1101          fprintf(stdout, "\n");          fprintf(stdout, "\n");
1102          matchptr += offsets[1];          matchptr += offsets[1];
1103          length -= offsets[1];          length -= offsets[1];
# Line 1189  while (ptr < endptr) Line 1234  while (ptr < endptr)
1234        else        else
1235  #endif  #endif
1236    
1237        /* We have to split the line(s) up if colouring. */        /* We have to split the line(s) up if colouring, and search for further
1238          matches. */
1239    
1240        if (do_colour)        if (do_colour)
1241          {          {
1242            int last_offset = 0;
1243          fwrite(ptr, 1, offsets[0], stdout);          fwrite(ptr, 1, offsets[0], stdout);
1244          fprintf(stdout, "%c[%sm", 0x1b, colour_string);          fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1245          fwrite(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);          fwrite(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
1246          fprintf(stdout, "%c[00m", 0x1b);          fprintf(stdout, "%c[00m", 0x1b);
1247          fwrite(ptr + offsets[1], 1, (linelength + endlinelength) - offsets[1],          for (;;)
1248              {
1249              last_offset += offsets[1];
1250              matchptr += offsets[1];
1251              length -= offsets[1];
1252              if (!match_patterns(matchptr, length, offsets, &mrc)) break;
1253              fwrite(matchptr, 1, offsets[0], stdout);
1254              fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1255              fwrite(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
1256              fprintf(stdout, "%c[00m", 0x1b);
1257              }
1258            fwrite(ptr + last_offset, 1, (linelength + endlinelength) - last_offset,
1259            stdout);            stdout);
1260          }          }
1261    
1262          /* Not colouring; no need to search for further matches */
1263    
1264        else fwrite(ptr, 1, linelength + endlinelength, stdout);        else fwrite(ptr, 1, linelength + endlinelength, stdout);
1265        }        }
1266    
# Line 1305  if (filenames == FN_NOMATCH_ONLY) Line 1366  if (filenames == FN_NOMATCH_ONLY)
1366    
1367  if (count_only)  if (count_only)
1368    {    {
1369    if (printname != NULL) fprintf(stdout, "%s:", printname);    if (count > 0 || !omit_zero_count)
1370    fprintf(stdout, "%d\n", count);      {
1371        if (printname != NULL && filenames != FN_NONE)
1372          fprintf(stdout, "%s:", printname);
1373        fprintf(stdout, "%d\n", count);
1374        }
1375    }    }
1376    
1377  return rc;  return rc;
# Line 1361  if (strcmp(pathname, "-") == 0) Line 1426  if (strcmp(pathname, "-") == 0)
1426    }    }
1427    
1428  /* If the file is a directory, skip if skipping or if we are recursing, scan  /* If the file is a directory, skip if skipping or if we are recursing, scan
1429  each file within it, subject to any include or exclude patterns that were set.  each file and directory within it, subject to any include or exclude patterns
1430  The scanning code is localized so it can be made system-specific. */  that were set. The scanning code is localized so it can be made
1431    system-specific. */
1432    
1433  if ((sep = isdirectory(pathname)) != 0)  if ((sep = isdirectory(pathname)) != 0)
1434    {    {
# Line 1383  if ((sep = isdirectory(pathname)) != 0) Line 1449  if ((sep = isdirectory(pathname)) != 0)
1449    
1450      while ((nextfile = readdirectory(dir)) != NULL)      while ((nextfile = readdirectory(dir)) != NULL)
1451        {        {
1452        int frc, blen;        int frc, nflen;
1453        sprintf(buffer, "%.512s%c%.128s", pathname, sep, nextfile);        sprintf(buffer, "%.512s%c%.128s", pathname, sep, nextfile);
1454        blen = strlen(buffer);        nflen = strlen(nextfile);
1455    
1456        if (exclude_compiled != NULL &&        if (isdirectory(buffer))
1457            pcre_exec(exclude_compiled, NULL, buffer, blen, 0, 0, NULL, 0) >= 0)          {
1458          continue;          if (exclude_dir_compiled != NULL &&
1459                pcre_exec(exclude_dir_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) >= 0)
1460        if (include_compiled != NULL &&            continue;
1461            pcre_exec(include_compiled, NULL, buffer, blen, 0, 0, NULL, 0) < 0)  
1462          continue;          if (include_dir_compiled != NULL &&
1463                pcre_exec(include_dir_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) < 0)
1464              continue;
1465            }
1466          else
1467            {
1468            if (exclude_compiled != NULL &&
1469                pcre_exec(exclude_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) >= 0)
1470              continue;
1471    
1472            if (include_compiled != NULL &&
1473                pcre_exec(include_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) < 0)
1474              continue;
1475            }
1476    
1477        frc = grep_or_recurse(buffer, dir_recurse, FALSE);        frc = grep_or_recurse(buffer, dir_recurse, FALSE);
1478        if (frc > 1) rc = frc;        if (frc > 1) rc = frc;
# Line 1456  an attempt to read a .bz2 file indicates Line 1535  an attempt to read a .bz2 file indicates
1535  PLAIN_FILE:  PLAIN_FILE:
1536  #endif  #endif
1537    {    {
1538    in = fopen(pathname, "r");    in = fopen(pathname, "rb");
1539    handle = (void *)in;    handle = (void *)in;
1540    frtype = FR_PLAIN;    frtype = FR_PLAIN;
1541    }    }
# Line 1579  for (op = optionlist; op->one_char != 0; Line 1658  for (op = optionlist; op->one_char != 0;
1658    int n;    int n;
1659    char s[4];    char s[4];
1660    if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, "   ");    if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, "   ");
1661    printf("  %s --%s%n", s, op->long_name, &n);    n = 30 - printf("  %s --%s", s, op->long_name);
   n = 30 - n;  
1662    if (n < 1) n = 1;    if (n < 1) n = 1;
1663    printf("%.*s%s\n", n, "                    ", op->help_text);    printf("%.*s%s\n", n, "                    ", op->help_text);
1664    }    }
# Line 1613  switch(letter) Line 1691  switch(letter)
1691    case 'H': filenames = FN_FORCE; break;    case 'H': filenames = FN_FORCE; break;
1692    case 'h': filenames = FN_NONE; break;    case 'h': filenames = FN_NONE; break;
1693    case 'i': options |= PCRE_CASELESS; break;    case 'i': options |= PCRE_CASELESS; break;
1694    case 'l': filenames = FN_ONLY; break;    case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break;
1695    case 'L': filenames = FN_NOMATCH_ONLY; break;    case 'L': filenames = FN_NOMATCH_ONLY; break;
1696    case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break;    case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break;
1697    case 'n': number = TRUE; break;    case 'n': number = TRUE; break;
# Line 1798  const char *error; Line 1876  const char *error;
1876    
1877  /* 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;
1878  "lf", "cr", "crlf", and "any" are supported. Anything else is treated as "lf".  "lf", "cr", "crlf", and "any" are supported. Anything else is treated as "lf".
1879  */  Note that the return values from pcre_config(), though derived from the ASCII
1880    codes, are the same in EBCDIC environments, so we must use the actual values
1881    rather than escapes such as as '\r'. */
1882    
1883  (void)pcre_config(PCRE_CONFIG_NEWLINE, &i);  (void)pcre_config(PCRE_CONFIG_NEWLINE, &i);
1884  switch(i)  switch(i)
1885    {    {
1886    default:                 newline = (char *)"lf"; break;    default:               newline = (char *)"lf"; break;
1887    case '\r':               newline = (char *)"cr"; break;    case 13:               newline = (char *)"cr"; break;
1888    case ('\r' << 8) | '\n': newline = (char *)"crlf"; break;    case (13 << 8) | 10:   newline = (char *)"crlf"; break;
1889    case -1:                 newline = (char *)"any"; break;    case -1:               newline = (char *)"any"; break;
1890    case -2:                 newline = (char *)"anycrlf"; break;    case -2:               newline = (char *)"anycrlf"; break;
1891    }    }
1892    
1893  /* Process the options */  /* Process the options */
# Line 1849  for (i = 1; i < argc; i++) Line 1929  for (i = 1; i < argc; i++)
1929      Some options have variations in the long name spelling: specifically, we      Some options have variations in the long name spelling: specifically, we
1930      allow "regexp" because GNU grep allows it, though I personally go along      allow "regexp" because GNU grep allows it, though I personally go along
1931      with Jeffrey Friedl and Larry Wall in preferring "regex" without the "p".      with Jeffrey Friedl and Larry Wall in preferring "regex" without the "p".
1932      These options are entered in the table as "regex(p)". No option is in both      These options are entered in the table as "regex(p)". Options can be in
1933      these categories, fortunately. */      both these categories. */
1934    
1935      for (op = optionlist; op->one_char != 0; op++)      for (op = optionlist; op->one_char != 0; op++)
1936        {        {
1937        char *opbra = strchr(op->long_name, '(');        char *opbra = strchr(op->long_name, '(');
1938        char *equals = strchr(op->long_name, '=');        char *equals = strchr(op->long_name, '=');
1939        if (opbra == NULL)     /* Not a (p) case */  
1940          /* Handle options with only one spelling of the name */
1941    
1942          if (opbra == NULL)     /* Does not contain '(' */
1943          {          {
1944          if (equals == NULL)  /* Not thing=data case */          if (equals == NULL)  /* Not thing=data case */
1945            {            {
# Line 1878  for (i = 1; i < argc; i++) Line 1961  for (i = 1; i < argc; i++)
1961              }              }
1962            }            }
1963          }          }
1964        else                   /* Special case xxxx(p) */  
1965          /* Handle options with an alternate spelling of the name */
1966    
1967          else
1968          {          {
1969          char buff1[24];          char buff1[24];
1970          char buff2[24];          char buff2[24];
1971    
1972          int baselen = opbra - op->long_name;          int baselen = opbra - op->long_name;
1973            int fulllen = strchr(op->long_name, ')') - op->long_name + 1;
1974            int arglen = (argequals == NULL || equals == NULL)?
1975              (int)strlen(arg) : argequals - arg;
1976    
1977          sprintf(buff1, "%.*s", baselen, op->long_name);          sprintf(buff1, "%.*s", baselen, op->long_name);
1978          sprintf(buff2, "%s%.*s", buff1,          sprintf(buff2, "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1);
1979            (int)strlen(op->long_name) - baselen - 2, opbra + 1);  
1980          if (strcmp(arg, buff1) == 0 || strcmp(arg, buff2) == 0)          if (strncmp(arg, buff1, arglen) == 0 ||
1981               strncmp(arg, buff2, arglen) == 0)
1982              {
1983              if (equals != NULL && argequals != NULL)
1984                {
1985                option_data = argequals;
1986                if (*option_data == '=')
1987                  {
1988                  option_data++;
1989                  longopwasequals = TRUE;
1990                  }
1991                }
1992            break;            break;
1993              }
1994          }          }
1995        }        }
1996    
# Line 1898  for (i = 1; i < argc; i++) Line 2001  for (i = 1; i < argc; i++)
2001        }        }
2002      }      }
2003    
   
2004    /* Jeffrey Friedl's debugging harness uses these additional options which    /* Jeffrey Friedl's debugging harness uses these additional options which
2005    are not in the right form for putting in the option table because they use    are not in the right form for putting in the option table because they use
2006    only one hyphen, yet are more than one character long. By putting them    only one hyphen, yet are more than one character long. By putting them
# Line 2288  if (include_pattern != NULL) Line 2390  if (include_pattern != NULL)
2390        errptr, error);        errptr, error);
2391      goto EXIT2;      goto EXIT2;
2392      }      }
2393      }
2394    
2395    if (exclude_dir_pattern != NULL)
2396      {
2397      exclude_dir_compiled = pcre_compile(exclude_dir_pattern, 0, &error, &errptr,
2398        pcretables);
2399      if (exclude_dir_compiled == NULL)
2400        {
2401        fprintf(stderr, "pcregrep: Error in 'exclude_dir' regex at offset %d: %s\n",
2402          errptr, error);
2403        goto EXIT2;
2404        }
2405      }
2406    
2407    if (include_dir_pattern != NULL)
2408      {
2409      include_dir_compiled = pcre_compile(include_dir_pattern, 0, &error, &errptr,
2410        pcretables);
2411      if (include_dir_compiled == NULL)
2412        {
2413        fprintf(stderr, "pcregrep: Error in 'include_dir' regex at offset %d: %s\n",
2414          errptr, error);
2415        goto EXIT2;
2416        }
2417    }    }
2418    
2419  /* 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. */

Legend:
Removed from v.286  
changed lines
  Added in v.490

  ViewVC Help
Powered by ViewVC 1.1.5