/[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 378 by ph10, Sun Mar 1 14:13:34 2009 UTC revision 422 by ph10, Fri Aug 14 16:42:55 2009 UTC
# Line 83  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 165  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 209  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 825  if (after_context > 0 && lastmatchnumber Line 826  if (after_context > 0 && lastmatchnumber
826  *   Apply patterns to subject till one matches   *  *   Apply patterns to subject till one matches   *
827  *************************************************/  *************************************************/
828    
829  /* This function is called to run through all patterns, looking for a match. It  /* 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  is used multiple times for the same subject when colouring is enabled, in order
831  to find all possible matches.  to find all possible matches.
832    
833  Arguments:  Arguments:
# Line 834  Arguments: Line 835  Arguments:
835    length      the length of the subject to match    length      the length of the subject to match
836    offsets     the offets vector to fill in    offsets     the offets vector to fill in
837    mrc         address of where to put the result of pcre_exec()    mrc         address of where to put the result of pcre_exec()
838    
839  Returns:      TRUE if there was a match  Returns:      TRUE if there was a match
840                FALSE if there was no match                FALSE if there was no match
841                invert if there was a non-fatal error                invert if there was a non-fatal error
842  */  */
843    
844  static BOOL  static BOOL
845  match_patterns(char *matchptr, size_t length, int *offsets, int *mrc)  match_patterns(char *matchptr, size_t length, int *offsets, int *mrc)
# Line 846  match_patterns(char *matchptr, size_t le Line 847  match_patterns(char *matchptr, size_t le
847  int i;  int i;
848  for (i = 0; i < pattern_count; i++)  for (i = 0; i < pattern_count; i++)
849    {    {
850    *mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, length, 0, 0,    *mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, length, 0,
851      offsets, OFFSET_SIZE);      PCRE_NOTEMPTY, offsets, OFFSET_SIZE);
852    if (*mrc >= 0) return TRUE;    if (*mrc >= 0) return TRUE;
853    if (*mrc == PCRE_ERROR_NOMATCH) continue;    if (*mrc == PCRE_ERROR_NOMATCH) continue;
854    fprintf(stderr, "pcregrep: pcre_exec() error %d while matching ", *mrc);    fprintf(stderr, "pcregrep: pcre_exec() error %d while matching ", *mrc);
# Line 992  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;        int i;
997    
998        if (jfriedl_XT)        if (jfriedl_XT)
999        {        {
# Line 1018  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, OFFSET_SIZE) >= 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 1037  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 or there is an error other    /* Run through all the patterns until one matches or there is an error other
1043    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
1044    finding subsequent matches when colouring matched lines. */    finding subsequent matches when colouring matched lines. */
1045    
1046    match = match_patterns(matchptr, length, offsets, &mrc);    match = match_patterns(matchptr, length, offsets, &mrc);
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. */
# Line 1060  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 1095  while (ptr < endptr) Line 1097  while (ptr < endptr)
1097            if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string);            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);            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 1232  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, and search for further        /* We have to split the line(s) up if colouring, and search for further
1238        matches. */        matches. */
1239    
1240        if (do_colour)        if (do_colour)
1241          {          {
1242          int last_offset = 0;          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          for (;;)          for (;;)
1248            {            {
1249            last_offset += offsets[1];            last_offset += offsets[1];
1250            matchptr += offsets[1];            matchptr += offsets[1];
1251            length -= offsets[1];            length -= offsets[1];
1252            if (!match_patterns(matchptr, length, offsets, &mrc)) break;            if (!match_patterns(matchptr, length, offsets, &mrc)) break;
# Line 1256  while (ptr < endptr) Line 1258  while (ptr < endptr)
1258          fwrite(ptr + last_offset, 1, (linelength + endlinelength) - last_offset,          fwrite(ptr + last_offset, 1, (linelength + endlinelength) - last_offset,
1259            stdout);            stdout);
1260          }          }
1261    
1262        /* Not colouring; no need to search for further matches */        /* 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 1364  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 1529  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 1685  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 1870  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 1921  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 1950  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 1970  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

Legend:
Removed from v.378  
changed lines
  Added in v.422

  ViewVC Help
Powered by ViewVC 1.1.5