/[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 589 by ph10, Sat Jan 15 11:31:39 2011 UTC revision 667 by ph10, Mon Aug 22 14:57:32 2011 UTC
# Line 74  typedef int BOOL; Line 74  typedef int BOOL;
74  #define OFFSET_SIZE 99  #define OFFSET_SIZE 99
75    
76  #if BUFSIZ > 8192  #if BUFSIZ > 8192
77  #define MBUFTHIRD BUFSIZ  #define PATBUFSIZE BUFSIZ
78  #else  #else
79  #define MBUFTHIRD 8192  #define PATBUFSIZE 8192
80  #endif  #endif
81    
82  /* Values for the "filenames" variable, which specifies options for file name  /* Values for the "filenames" variable, which specifies options for file name
# Line 135  static char *colour_string = (char *)"1; Line 135  static char *colour_string = (char *)"1;
135  static char *colour_option = NULL;  static char *colour_option = NULL;
136  static char *dee_option = NULL;  static char *dee_option = NULL;
137  static char *DEE_option = NULL;  static char *DEE_option = NULL;
138    static char *main_buffer = NULL;
139  static char *newline = NULL;  static char *newline = NULL;
140  static char *pattern_filename = NULL;  static char *pattern_filename = NULL;
141  static char *stdin_name = (char *)"(standard input)";  static char *stdin_name = (char *)"(standard input)";
# Line 159  static pcre *exclude_dir_compiled = NULL Line 160  static pcre *exclude_dir_compiled = NULL
160  static int after_context = 0;  static int after_context = 0;
161  static int before_context = 0;  static int before_context = 0;
162  static int both_context = 0;  static int both_context = 0;
163    static int bufthird = PCREGREP_BUFSIZE;
164    static int bufsize = 3*PCREGREP_BUFSIZE;
165  static int dee_action = dee_READ;  static int dee_action = dee_READ;
166  static int DEE_action = DEE_READ;  static int DEE_action = DEE_READ;
167  static int error_count = 0;  static int error_count = 0;
168  static int filenames = FN_DEFAULT;  static int filenames = FN_DEFAULT;
169  static int only_matching = -1;  static int only_matching = -1;
170  static int process_options = 0;  static int process_options = 0;
171    static int study_options = 0;
172    
173  static unsigned long int match_limit = 0;  static unsigned long int match_limit = 0;
174  static unsigned long int match_limit_recursion = 0;  static unsigned long int match_limit_recursion = 0;
# Line 214  used to identify them. */ Line 218  used to identify them. */
218  #define N_LBUFFER      (-12)  #define N_LBUFFER      (-12)
219  #define N_M_LIMIT      (-13)  #define N_M_LIMIT      (-13)
220  #define N_M_LIMIT_REC  (-14)  #define N_M_LIMIT_REC  (-14)
221    #define N_BUFSIZE      (-15)
222    
223  static option_item optionlist[] = {  static option_item optionlist[] = {
224    { OP_NODATA,     N_NULL,   NULL,              "",              "  terminate options" },    { OP_NODATA,     N_NULL,   NULL,              "",              "  terminate options" },
225    { OP_NODATA,     N_HELP,   NULL,              "help",          "display this help and exit" },    { OP_NODATA,     N_HELP,   NULL,              "help",          "display this help and exit" },
226    { OP_NUMBER,     'A',      &after_context,    "after-context=number", "set number of following context lines" },    { OP_NUMBER,     'A',      &after_context,    "after-context=number", "set number of following context lines" },
227    { OP_NUMBER,     'B',      &before_context,   "before-context=number", "set number of prior context lines" },    { OP_NUMBER,     'B',      &before_context,   "before-context=number", "set number of prior context lines" },
228      { OP_NUMBER,     N_BUFSIZE,&bufthird,         "buffer-size=number", "set processing buffer size parameter" },
229    { OP_OP_STRING,  N_COLOUR, &colour_option,    "color=option",  "matched text color option" },    { OP_OP_STRING,  N_COLOUR, &colour_option,    "color=option",  "matched text color option" },
230    { 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" },
231    { OP_NUMBER,     'C',      &both_context,     "context=number", "set number of context lines, before & after" },    { OP_NUMBER,     'C',      &both_context,     "context=number", "set number of context lines, before & after" },
# Line 233  static option_item optionlist[] = { Line 239  static option_item optionlist[] = {
239    { OP_NODATA,     'H',      NULL,              "with-filename", "force the prefixing filename on output" },    { OP_NODATA,     'H',      NULL,              "with-filename", "force the prefixing filename on output" },
240    { OP_NODATA,     'h',      NULL,              "no-filename",   "suppress the prefixing filename on output" },    { OP_NODATA,     'h',      NULL,              "no-filename",   "suppress the prefixing filename on output" },
241    { OP_NODATA,     'i',      NULL,              "ignore-case",   "ignore case distinctions" },    { OP_NODATA,     'i',      NULL,              "ignore-case",   "ignore case distinctions" },
242      { OP_NODATA,     'j',      NULL,              "jit",           "use JIT compiler if available" },
243    { 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" },
244    { 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" },
245    { 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" },
# Line 634  Arguments: Line 641  Arguments:
641    endptr    end of available data    endptr    end of available data
642    lenptr    where to put the length of the eol sequence    lenptr    where to put the length of the eol sequence
643    
644  Returns:    pointer to the last byte of the line, including the newline byte(s)  Returns:    pointer after the last byte of the line,
645                including the newline byte(s)
646  */  */
647    
648  static char *  static char *
# Line 935  is used multiple times for the same subj Line 943  is used multiple times for the same subj
943  to find all possible matches.  to find all possible matches.
944    
945  Arguments:  Arguments:
946    matchptr    the start of the subject    matchptr     the start of the subject
947    length      the length of the subject to match    length       the length of the subject to match
948    offsets     the offets vector to fill in    startoffset  where to start matching
949    mrc         address of where to put the result of pcre_exec()    offsets      the offets vector to fill in
950      mrc          address of where to put the result of pcre_exec()
951    
952  Returns:      TRUE if there was a match  Returns:      TRUE if there was a match
953                FALSE if there was no match                FALSE if there was no match
# Line 946  Returns: TRUE if there was a match Line 955  Returns: TRUE if there was a match
955  */  */
956    
957  static BOOL  static BOOL
958  match_patterns(char *matchptr, size_t length, int *offsets, int *mrc)  match_patterns(char *matchptr, size_t length, int startoffset, int *offsets,
959      int *mrc)
960  {  {
961  int i;  int i;
962  size_t slen = length;  size_t slen = length;
# Line 958  if (slen > 200) Line 968  if (slen > 200)
968    }    }
969  for (i = 0; i < pattern_count; i++)  for (i = 0; i < pattern_count; i++)
970    {    {
971    *mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, (int)length, 0,    *mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, (int)length,
972      PCRE_NOTEMPTY, offsets, OFFSET_SIZE);      startoffset, PCRE_NOTEMPTY, offsets, OFFSET_SIZE);
973    if (*mrc >= 0) return TRUE;    if (*mrc >= 0) return TRUE;
974    if (*mrc == PCRE_ERROR_NOMATCH) continue;    if (*mrc == PCRE_ERROR_NOMATCH) continue;
975    fprintf(stderr, "pcregrep: pcre_exec() gave error %d while matching ", *mrc);    fprintf(stderr, "pcregrep: pcre_exec() gave error %d while matching ", *mrc);
# Line 987  return FALSE; /* No match, no errors */ Line 997  return FALSE; /* No match, no errors */
997  *************************************************/  *************************************************/
998    
999  /* This is called from grep_or_recurse() below. It uses a buffer that is three  /* This is called from grep_or_recurse() below. It uses a buffer that is three
1000  times the value of MBUFTHIRD. The matching point is never allowed to stray into  times the value of bufthird. The matching point is never allowed to stray into
1001  the top third of the buffer, thus keeping more of the file available for  the top third of the buffer, thus keeping more of the file available for
1002  context printing or for multiline scanning. For large files, the pointer will  context printing or for multiline scanning. For large files, the pointer will
1003  be in the middle third most of the time, so the bottom third is available for  be in the middle third most of the time, so the bottom third is available for
# Line 998  Arguments: Line 1008  Arguments:
1008                 the gzFile pointer when reading is via libz                 the gzFile pointer when reading is via libz
1009                 the BZFILE pointer when reading is via libbz2                 the BZFILE pointer when reading is via libbz2
1010    frtype       FR_PLAIN, FR_LIBZ, or FR_LIBBZ2    frtype       FR_PLAIN, FR_LIBZ, or FR_LIBBZ2
1011      filename     the file name or NULL (for errors)
1012    printname    the file name if it is to be printed for each match    printname    the file name if it is to be printed for each match
1013                 or NULL if the file name is not to be printed                 or NULL if the file name is not to be printed
1014                 it cannot be NULL if filenames[_nomatch]_only is set                 it cannot be NULL if filenames[_nomatch]_only is set
1015    
1016  Returns:       0 if there was at least one match  Returns:       0 if there was at least one match
1017                 1 otherwise (no matches)                 1 otherwise (no matches)
1018                 2 if there is a read error on a .bz2 file                 2 if an overlong line is encountered
1019                   3 if there is a read error on a .bz2 file
1020  */  */
1021    
1022  static int  static int
1023  pcregrep(void *handle, int frtype, char *printname)  pcregrep(void *handle, int frtype, char *filename, char *printname)
1024  {  {
1025  int rc = 1;  int rc = 1;
1026  int linenumber = 1;  int linenumber = 1;
# Line 1017  int count = 0; Line 1029  int count = 0;
1029  int filepos = 0;  int filepos = 0;
1030  int offsets[OFFSET_SIZE];  int offsets[OFFSET_SIZE];
1031  char *lastmatchrestart = NULL;  char *lastmatchrestart = NULL;
1032  char buffer[3*MBUFTHIRD];  char *ptr = main_buffer;
 char *ptr = buffer;  
1033  char *endptr;  char *endptr;
1034  size_t bufflength;  size_t bufflength;
1035  BOOL endhyphenpending = FALSE;  BOOL endhyphenpending = FALSE;
# Line 1043  fail. */ Line 1054  fail. */
1054  if (frtype == FR_LIBZ)  if (frtype == FR_LIBZ)
1055    {    {
1056    ingz = (gzFile)handle;    ingz = (gzFile)handle;
1057    bufflength = gzread (ingz, buffer, 3*MBUFTHIRD);    bufflength = gzread (ingz, main_buffer, bufsize);
1058    }    }
1059  else  else
1060  #endif  #endif
# Line 1052  else Line 1063  else
1063  if (frtype == FR_LIBBZ2)  if (frtype == FR_LIBBZ2)
1064    {    {
1065    inbz2 = (BZFILE *)handle;    inbz2 = (BZFILE *)handle;
1066    bufflength = BZ2_bzread(inbz2, buffer, 3*MBUFTHIRD);    bufflength = BZ2_bzread(inbz2, main_buffer, bufsize);
1067    if ((int)bufflength < 0) return 2;   /* Gotcha: bufflength is size_t; */    if ((int)bufflength < 0) return 2;   /* Gotcha: bufflength is size_t; */
1068    }                                    /* without the cast it is unsigned. */    }                                    /* without the cast it is unsigned. */
1069  else  else
# Line 1062  else Line 1073  else
1073    in = (FILE *)handle;    in = (FILE *)handle;
1074    if (is_file_tty(in)) input_line_buffered = TRUE;    if (is_file_tty(in)) input_line_buffered = TRUE;
1075    bufflength = input_line_buffered?    bufflength = input_line_buffered?
1076      read_one_line(buffer, 3*MBUFTHIRD, in) :      read_one_line(main_buffer, bufsize, in) :
1077      fread(buffer, 1, 3*MBUFTHIRD, in);      fread(main_buffer, 1, bufsize, in);
1078    }    }
1079    
1080  endptr = buffer + bufflength;  endptr = main_buffer + bufflength;
1081    
1082  /* Loop while the current pointer is not at the end of the file. For large  /* Loop while the current pointer is not at the end of the file. For large
1083  files, endptr will be at the end of the buffer when we are in the middle of the  files, endptr will be at the end of the buffer when we are in the middle of the
# Line 1077  while (ptr < endptr) Line 1088  while (ptr < endptr)
1088    {    {
1089    int endlinelength;    int endlinelength;
1090    int mrc = 0;    int mrc = 0;
1091      int startoffset = 0;
1092    BOOL match;    BOOL match;
1093    char *matchptr = ptr;    char *matchptr = ptr;
1094    char *t = ptr;    char *t = ptr;
# Line 1094  while (ptr < endptr) Line 1106  while (ptr < endptr)
1106    linelength = t - ptr - endlinelength;    linelength = t - ptr - endlinelength;
1107    length = multiline? (size_t)(endptr - ptr) : linelength;    length = multiline? (size_t)(endptr - ptr) : linelength;
1108    
1109      /* Check to see if the line we are looking at extends right to the very end
1110      of the buffer without a line terminator. This means the line is too long to
1111      handle. */
1112    
1113      if (endlinelength == 0 && t == main_buffer + bufsize)
1114        {
1115        fprintf(stderr, "pcregrep: line %d%s%s is too long for the internal buffer\n"
1116                        "pcregrep: check the --buffer-size option\n",
1117                        linenumber,
1118                        (filename == NULL)? "" : " of file ",
1119                        (filename == NULL)? "" : filename);
1120        return 2;
1121        }
1122    
1123    /* Extra processing for Jeffrey Friedl's debugging. */    /* Extra processing for Jeffrey Friedl's debugging. */
1124    
1125  #ifdef JFRIEDL_DEBUG  #ifdef JFRIEDL_DEBUG
# Line 1153  while (ptr < endptr) Line 1179  while (ptr < endptr)
1179    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
1180    finding subsequent matches when colouring matched lines. */    finding subsequent matches when colouring matched lines. */
1181    
1182    match = match_patterns(matchptr, length, offsets, &mrc);    match = match_patterns(matchptr, length, startoffset, offsets, &mrc);
1183    
1184    /* 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. */
1185    
# Line 1186  while (ptr < endptr) Line 1212  while (ptr < endptr)
1212      captured portion of it, as long as this string is not empty, and the      captured portion of it, as long as this string is not empty, and the
1213      --file-offsets and --line-offsets options output offsets for the matching      --file-offsets and --line-offsets options output offsets for the matching
1214      substring (they both force --only-matching = 0). None of these options      substring (they both force --only-matching = 0). None of these options
1215      prints any context. Afterwards, adjust the start and length, and then jump      prints any context. Afterwards, adjust the start and then jump back to look
1216      back to look for further matches in the same line. If we are in invert      for further matches in the same line. If we are in invert mode, however,
1217      mode, however, nothing is printed and we do not restart - this could still      nothing is printed and we do not restart - this could still be useful
1218      be useful because the return code is set. */      because the return code is set. */
1219    
1220      else if (only_matching >= 0)      else if (only_matching >= 0)
1221        {        {
# Line 1216  while (ptr < endptr) Line 1242  while (ptr < endptr)
1242              }              }
1243            }            }
1244          else if (printname != NULL || number) fprintf(stdout, "\n");          else if (printname != NULL || number) fprintf(stdout, "\n");
         matchptr += offsets[1];  
         length -= offsets[1];  
1245          match = FALSE;          match = FALSE;
1246          if (line_buffered) fflush(stdout);          if (line_buffered) fflush(stdout);
1247          rc = 0;    /* Had some success */          rc = 0;                      /* Had some success */
1248            startoffset = offsets[1];    /* Restart after the match */
1249          goto ONLY_MATCHING_RESTART;          goto ONLY_MATCHING_RESTART;
1250          }          }
1251        }        }
# Line 1279  while (ptr < endptr) Line 1304  while (ptr < endptr)
1304          int linecount = 0;          int linecount = 0;
1305          char *p = ptr;          char *p = ptr;
1306    
1307          while (p > buffer && (lastmatchnumber == 0 || p > lastmatchrestart) &&          while (p > main_buffer && (lastmatchnumber == 0 || p > lastmatchrestart) &&
1308                 linecount < before_context)                 linecount < before_context)
1309            {            {
1310            linecount++;            linecount++;
1311            p = previous_line(p, buffer);            p = previous_line(p, main_buffer);
1312            }            }
1313    
1314          if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted)          if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted)
# Line 1353  while (ptr < endptr) Line 1378  while (ptr < endptr)
1378        if (do_colour && !invert)        if (do_colour && !invert)
1379          {          {
1380          int plength;          int plength;
         int last_offset = 0;  
1381          FWRITE(ptr, 1, offsets[0], stdout);          FWRITE(ptr, 1, offsets[0], stdout);
1382          fprintf(stdout, "%c[%sm", 0x1b, colour_string);          fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1383          FWRITE(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);          FWRITE(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
1384          fprintf(stdout, "%c[00m", 0x1b);          fprintf(stdout, "%c[00m", 0x1b);
1385          for (;;)          for (;;)
1386            {            {
1387            last_offset += offsets[1];            startoffset = offsets[1];
1388            matchptr += offsets[1];            if (startoffset >= linelength + endlinelength ||
1389            length -= offsets[1];                !match_patterns(matchptr, length, startoffset, offsets, &mrc))
1390            if (last_offset >= linelength + endlinelength ||              break;
1391                !match_patterns(matchptr, length, offsets, &mrc)) break;            FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout);
           FWRITE(matchptr, 1, offsets[0], stdout);  
1392            fprintf(stdout, "%c[%sm", 0x1b, colour_string);            fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1393            FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);            FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
1394            fprintf(stdout, "%c[00m", 0x1b);            fprintf(stdout, "%c[00m", 0x1b);
# Line 1375  while (ptr < endptr) Line 1398  while (ptr < endptr)
1398          and its line-ending characters (if they matched the pattern), so there          and its line-ending characters (if they matched the pattern), so there
1399          may be no more to print. */          may be no more to print. */
1400    
1401          plength = (linelength + endlinelength) - last_offset;          plength = (linelength + endlinelength) - startoffset;
1402          if (plength > 0)          if (plength > 0) FWRITE(ptr + startoffset, 1, plength, stdout);
           FWRITE(ptr + last_offset, 1, plength, stdout);  
1403          }          }
1404    
1405        /* Not colouring; no need to search for further matches */        /* Not colouring; no need to search for further matches */
# Line 1426  while (ptr < endptr) Line 1448  while (ptr < endptr)
1448    /* If input is line buffered, and the buffer is not yet full, read another    /* If input is line buffered, and the buffer is not yet full, read another
1449    line and add it into the buffer. */    line and add it into the buffer. */
1450    
1451    if (input_line_buffered && bufflength < sizeof(buffer))    if (input_line_buffered && bufflength < bufsize)
1452      {      {
1453      int add = read_one_line(ptr, sizeof(buffer) - (ptr - buffer), in);      int add = read_one_line(ptr, bufsize - (ptr - main_buffer), in);
1454      bufflength += add;      bufflength += add;
1455      endptr += add;      endptr += add;
1456      }      }
# Line 1438  while (ptr < endptr) Line 1460  while (ptr < endptr)
1460    1/3 and refill it. Before we do this, if some unprinted "after" lines are    1/3 and refill it. Before we do this, if some unprinted "after" lines are
1461    about to be lost, print them. */    about to be lost, print them. */
1462    
1463    if (bufflength >= sizeof(buffer) && ptr > buffer + 2*MBUFTHIRD)    if (bufflength >= bufsize && ptr > main_buffer + 2*bufthird)
1464      {      {
1465      if (after_context > 0 &&      if (after_context > 0 &&
1466          lastmatchnumber > 0 &&          lastmatchnumber > 0 &&
1467          lastmatchrestart < buffer + MBUFTHIRD)          lastmatchrestart < main_buffer + bufthird)
1468        {        {
1469        do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);        do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);
1470        lastmatchnumber = 0;        lastmatchnumber = 0;
# Line 1450  while (ptr < endptr) Line 1472  while (ptr < endptr)
1472    
1473      /* Now do the shuffle */      /* Now do the shuffle */
1474    
1475      memmove(buffer, buffer + MBUFTHIRD, 2*MBUFTHIRD);      memmove(main_buffer, main_buffer + bufthird, 2*bufthird);
1476      ptr -= MBUFTHIRD;      ptr -= bufthird;
1477    
1478  #ifdef SUPPORT_LIBZ  #ifdef SUPPORT_LIBZ
1479      if (frtype == FR_LIBZ)      if (frtype == FR_LIBZ)
1480        bufflength = 2*MBUFTHIRD +        bufflength = 2*bufthird +
1481          gzread (ingz, buffer + 2*MBUFTHIRD, MBUFTHIRD);          gzread (ingz, main_buffer + 2*bufthird, bufthird);
1482      else      else
1483  #endif  #endif
1484    
1485  #ifdef SUPPORT_LIBBZ2  #ifdef SUPPORT_LIBBZ2
1486      if (frtype == FR_LIBBZ2)      if (frtype == FR_LIBBZ2)
1487        bufflength = 2*MBUFTHIRD +        bufflength = 2*bufthird +
1488          BZ2_bzread(inbz2, buffer + 2*MBUFTHIRD, MBUFTHIRD);          BZ2_bzread(inbz2, main_buffer + 2*bufthird, bufthird);
1489      else      else
1490  #endif  #endif
1491    
1492      bufflength = 2*MBUFTHIRD +      bufflength = 2*bufthird +
1493        (input_line_buffered?        (input_line_buffered?
1494         read_one_line(buffer + 2*MBUFTHIRD, MBUFTHIRD, in) :         read_one_line(main_buffer + 2*bufthird, bufthird, in) :
1495         fread(buffer + 2*MBUFTHIRD, 1, MBUFTHIRD, in));         fread(main_buffer + 2*bufthird, 1, bufthird, in));
1496      endptr = buffer + bufflength;      endptr = main_buffer + bufflength;
1497    
1498      /* Adjust any last match point */      /* Adjust any last match point */
1499    
1500      if (lastmatchnumber > 0) lastmatchrestart -= MBUFTHIRD;      if (lastmatchnumber > 0) lastmatchrestart -= bufthird;
1501      }      }
1502    }     /* Loop through the whole file */    }     /* Loop through the whole file */
1503    
# Line 1555  BZFILE *inbz2 = NULL; Line 1577  BZFILE *inbz2 = NULL;
1577    
1578  if (strcmp(pathname, "-") == 0)  if (strcmp(pathname, "-") == 0)
1579    {    {
1580    return pcregrep(stdin, FR_PLAIN,    return pcregrep(stdin, FR_PLAIN, stdin_name,
1581      (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))?      (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))?
1582        stdin_name : NULL);        stdin_name : NULL);
1583    }    }
# Line 1687  if (handle == NULL) Line 1709  if (handle == NULL)
1709    
1710  /* Now grep the file */  /* Now grep the file */
1711    
1712  rc = pcregrep(handle, frtype, (filenames > FN_DEFAULT ||  rc = pcregrep(handle, frtype, pathname, (filenames > FN_DEFAULT ||
1713    (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL);    (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL);
1714    
1715  /* Close in an appropriate manner. */  /* Close in an appropriate manner. */
# Line 1698  if (frtype == FR_LIBZ) Line 1720  if (frtype == FR_LIBZ)
1720  else  else
1721  #endif  #endif
1722    
1723  /* If it is a .bz2 file and the result is 2, it means that the first attempt to  /* If it is a .bz2 file and the result is 3, it means that the first attempt to
1724  read failed. If the error indicates that the file isn't in fact bzipped, try  read failed. If the error indicates that the file isn't in fact bzipped, try
1725  again as a normal file. */  again as a normal file. */
1726    
1727  #ifdef SUPPORT_LIBBZ2  #ifdef SUPPORT_LIBBZ2
1728  if (frtype == FR_LIBBZ2)  if (frtype == FR_LIBBZ2)
1729    {    {
1730    if (rc == 2)    if (rc == 3)
1731      {      {
1732      int errnum;      int errnum;
1733      const char *err = BZ2_bzerror(inbz2, &errnum);      const char *err = BZ2_bzerror(inbz2, &errnum);
# Line 1717  if (frtype == FR_LIBBZ2) Line 1739  if (frtype == FR_LIBBZ2)
1739      else if (!silent)      else if (!silent)
1740        fprintf(stderr, "pcregrep: Failed to read %s using bzlib: %s\n",        fprintf(stderr, "pcregrep: Failed to read %s using bzlib: %s\n",
1741          pathname, err);          pathname, err);
1742        rc = 2;    /* The normal "something went wrong" code */
1743      }      }
1744    BZ2_bzclose(inbz2);    BZ2_bzclose(inbz2);
1745    }    }
# Line 1809  for (op = optionlist; op->one_char != 0; Line 1832  for (op = optionlist; op->one_char != 0;
1832    printf("%.*s%s\n", n, "                     ", op->help_text);    printf("%.*s%s\n", n, "                     ", op->help_text);
1833    }    }
1834    
1835  printf("\nWhen reading patterns from a file instead of using a command line option,\n");  printf("\nNumbers may be followed by K or M, e.g. --buffer-size=100K.\n");
1836    printf("The default value for --buffer-size is %d.\n", PCREGREP_BUFSIZE);
1837    printf("When reading patterns from a file instead of using a command line option,\n");
1838  printf("trailing white space is removed and blank lines are ignored.\n");  printf("trailing white space is removed and blank lines are ignored.\n");
1839  printf("There is a maximum of %d patterns.\n", MAX_PATTERN_COUNT);  printf("There is a maximum of %d patterns, each of maximum size %d bytes.\n",
1840      MAX_PATTERN_COUNT, PATBUFSIZE);
1841    
1842  printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n");  printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n");
1843  printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n");  printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n");
# Line 1838  switch(letter) Line 1864  switch(letter)
1864    case 'H': filenames = FN_FORCE; break;    case 'H': filenames = FN_FORCE; break;
1865    case 'h': filenames = FN_NONE; break;    case 'h': filenames = FN_NONE; break;
1866    case 'i': options |= PCRE_CASELESS; break;    case 'i': options |= PCRE_CASELESS; break;
1867      case 'j': study_options |= PCRE_STUDY_JIT_COMPILE; break;
1868    case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break;    case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break;
1869    case 'L': filenames = FN_NOMATCH_ONLY; break;    case 'L': filenames = FN_NOMATCH_ONLY; break;
1870    case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break;    case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break;
# Line 1913  Returns: TRUE on success, FALSE Line 1940  Returns: TRUE on success, FALSE
1940  static BOOL  static BOOL
1941  compile_single_pattern(char *pattern, int options, char *filename, int count)  compile_single_pattern(char *pattern, int options, char *filename, int count)
1942  {  {
1943  char buffer[MBUFTHIRD + 16];  char buffer[PATBUFSIZE];
1944  const char *error;  const char *error;
1945  int errptr;  int errptr;
1946    
# Line 1924  if (pattern_count >= MAX_PATTERN_COUNT) Line 1951  if (pattern_count >= MAX_PATTERN_COUNT)
1951    return FALSE;    return FALSE;
1952    }    }
1953    
1954  sprintf(buffer, "%s%.*s%s", prefix[process_options], MBUFTHIRD, pattern,  sprintf(buffer, "%s%.*s%s", prefix[process_options], bufthird, pattern,
1955    suffix[process_options]);    suffix[process_options]);
1956  pattern_list[pattern_count] =  pattern_list[pattern_count] =
1957    pcre_compile(buffer, options, &error, &errptr, pcretables);    pcre_compile(buffer, options, &error, &errptr, pcretables);
# Line 1983  compile_pattern(char *pattern, int optio Line 2010  compile_pattern(char *pattern, int optio
2010  if ((process_options & PO_FIXED_STRINGS) != 0)  if ((process_options & PO_FIXED_STRINGS) != 0)
2011    {    {
2012    char *eop = pattern + strlen(pattern);    char *eop = pattern + strlen(pattern);
2013    char buffer[MBUFTHIRD];    char buffer[PATBUFSIZE];
2014    for(;;)    for(;;)
2015      {      {
2016      int ellength;      int ellength;
# Line 2295  for (i = 1; i < argc; i++) Line 2322  for (i = 1; i < argc; i++)
2322      while (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++;      while (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++;
2323      while (isdigit((unsigned char)(*endptr)))      while (isdigit((unsigned char)(*endptr)))
2324        n = n * 10 + (int)(*endptr++ - '0');        n = n * 10 + (int)(*endptr++ - '0');
2325        if (toupper(*endptr) == 'K')
2326          {
2327          n *= 1024;
2328          endptr++;
2329          }
2330        else if (toupper(*endptr) == 'M')
2331          {
2332          n *= 1024*1024;
2333          endptr++;
2334          }
2335      if (*endptr != 0)      if (*endptr != 0)
2336        {        {
2337        if (longop)        if (longop)
# Line 2461  if (jfriedl_XT != 0 || jfriedl_XR != 0) Line 2498  if (jfriedl_XT != 0 || jfriedl_XR != 0)
2498    }    }
2499  #endif  #endif
2500    
2501  /* Get memory to store the pattern and hints lists. */  /* Get memory for the main buffer, and to store the pattern and hints lists. */
2502    
2503    bufsize = 3*bufthird;
2504    main_buffer = (char *)malloc(bufsize);
2505  pattern_list = (pcre **)malloc(MAX_PATTERN_COUNT * sizeof(pcre *));  pattern_list = (pcre **)malloc(MAX_PATTERN_COUNT * sizeof(pcre *));
2506  hints_list = (pcre_extra **)malloc(MAX_PATTERN_COUNT * sizeof(pcre_extra *));  hints_list = (pcre_extra **)malloc(MAX_PATTERN_COUNT * sizeof(pcre_extra *));
2507    
2508  if (pattern_list == NULL || hints_list == NULL)  if (main_buffer == NULL || pattern_list == NULL || hints_list == NULL)
2509    {    {
2510    fprintf(stderr, "pcregrep: malloc failed\n");    fprintf(stderr, "pcregrep: malloc failed\n");
2511    goto EXIT2;    goto EXIT2;
# Line 2498  if (pattern_filename != NULL) Line 2537  if (pattern_filename != NULL)
2537    int linenumber = 0;    int linenumber = 0;
2538    FILE *f;    FILE *f;
2539    char *filename;    char *filename;
2540    char buffer[MBUFTHIRD];    char buffer[PATBUFSIZE];
2541    
2542    if (strcmp(pattern_filename, "-") == 0)    if (strcmp(pattern_filename, "-") == 0)
2543      {      {
# Line 2517  if (pattern_filename != NULL) Line 2556  if (pattern_filename != NULL)
2556      filename = pattern_filename;      filename = pattern_filename;
2557      }      }
2558    
2559    while (fgets(buffer, MBUFTHIRD, f) != NULL)    while (fgets(buffer, PATBUFSIZE, f) != NULL)
2560      {      {
2561      char *s = buffer + (int)strlen(buffer);      char *s = buffer + (int)strlen(buffer);
2562      while (s > buffer && isspace((unsigned char)(s[-1]))) s--;      while (s > buffer && isspace((unsigned char)(s[-1]))) s--;
# Line 2535  if (pattern_filename != NULL) Line 2574  if (pattern_filename != NULL)
2574    
2575  for (j = 0; j < pattern_count; j++)  for (j = 0; j < pattern_count; j++)
2576    {    {
2577    hints_list[j] = pcre_study(pattern_list[j], 0, &error);    hints_list[j] = pcre_study(pattern_list[j], study_options, &error);
2578    if (error != NULL)    if (error != NULL)
2579      {      {
2580      char s[16];      char s[16];
# Line 2629  if (include_dir_pattern != NULL) Line 2668  if (include_dir_pattern != NULL)
2668    
2669  if (i >= argc)  if (i >= argc)
2670    {    {
2671    rc = pcregrep(stdin, FR_PLAIN, (filenames > FN_DEFAULT)? stdin_name : NULL);    rc = pcregrep(stdin, FR_PLAIN, stdin_name,
2672        (filenames > FN_DEFAULT)? stdin_name : NULL);
2673    goto EXIT;    goto EXIT;
2674    }    }
2675    
# Line 2649  for (; i < argc; i++) Line 2689  for (; i < argc; i++)
2689    }    }
2690    
2691  EXIT:  EXIT:
2692    if (main_buffer != NULL) free(main_buffer);
2693  if (pattern_list != NULL)  if (pattern_list != NULL)
2694    {    {
2695    for (i = 0; i < pattern_count; i++) free(pattern_list[i]);    for (i = 0; i < pattern_count; i++) free(pattern_list[i]);
# Line 2658  if (hints_list != NULL) Line 2699  if (hints_list != NULL)
2699    {    {
2700    for (i = 0; i < hint_count; i++)    for (i = 0; i < hint_count; i++)
2701      {      {
2702      if (hints_list[i] != NULL) free(hints_list[i]);      if (hints_list[i] != NULL) pcre_free_study(hints_list[i]);
2703      }      }
2704    free(hints_list);    free(hints_list);
2705    }    }

Legend:
Removed from v.589  
changed lines
  Added in v.667

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12