/[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 560 by ph10, Tue Oct 26 15:26:45 2010 UTC revision 561 by ph10, Sat Oct 30 18:37:47 2010 UTC
# Line 165  static int error_count = 0; Line 165  static int error_count = 0;
165  static int filenames = FN_DEFAULT;  static int filenames = FN_DEFAULT;
166  static int process_options = 0;  static int process_options = 0;
167    
168    static unsigned long int match_limit = 0;
169    static unsigned long int match_limit_recursion = 0;
170    
171  static BOOL count_only = FALSE;  static BOOL count_only = FALSE;
172  static BOOL do_colour = FALSE;  static BOOL do_colour = FALSE;
173  static BOOL file_offsets = FALSE;  static BOOL file_offsets = FALSE;
# Line 176  static BOOL multiline = FALSE; Line 179  static BOOL multiline = FALSE;
179  static BOOL number = FALSE;  static BOOL number = FALSE;
180  static BOOL omit_zero_count = FALSE;  static BOOL omit_zero_count = FALSE;
181  static BOOL only_matching = FALSE;  static BOOL only_matching = FALSE;
182    static BOOL resource_error = FALSE;
183  static BOOL quiet = FALSE;  static BOOL quiet = FALSE;
184  static BOOL silent = FALSE;  static BOOL silent = FALSE;
185  static BOOL utf8 = FALSE;  static BOOL utf8 = FALSE;
# Line 208  used to identify them. */ Line 212  used to identify them. */
212  #define N_LOFFSETS     (-10)  #define N_LOFFSETS     (-10)
213  #define N_FOFFSETS     (-11)  #define N_FOFFSETS     (-11)
214  #define N_LBUFFER      (-12)  #define N_LBUFFER      (-12)
215    #define N_M_LIMIT      (-13)
216    #define N_M_LIMIT_REC  (-14)
217    
218  static option_item optionlist[] = {  static option_item optionlist[] = {
219    { OP_NODATA,    N_NULL,   NULL,              "",              "  terminate options" },    { OP_NODATA,    N_NULL,   NULL,              "",              "  terminate options" },
# Line 215  static option_item optionlist[] = { Line 221  static option_item optionlist[] = {
221    { 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" },
222    { 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" },
223    { 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" },
224      { OP_OP_STRING, N_COLOUR, &colour_option,    "colour=option", "matched text colour option" },
225    { 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" },
226    { OP_NODATA,    'c',      NULL,              "count",         "print only a count of matching lines per FILE" },    { OP_NODATA,    'c',      NULL,              "count",         "print only a count of matching lines per FILE" },
   { OP_OP_STRING, N_COLOUR, &colour_option,    "colour=option", "matched text colour option" },  
227    { 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" },
228    { OP_STRING,    'd',      &dee_option,       "directories=action", "how to handle directories" },    { OP_STRING,    'd',      &dee_option,       "directories=action", "how to handle directories" },
229    { OP_PATLIST,   'e',      NULL,              "regex(p)=pattern", "specify pattern (may be used more than once)" },    { OP_PATLIST,   'e',      NULL,              "regex(p)=pattern", "specify pattern (may be used more than once)" },
# Line 233  static option_item optionlist[] = { Line 239  static option_item optionlist[] = {
239    { OP_NODATA,    N_LBUFFER, NULL,             "line-buffered", "use line buffering" },    { OP_NODATA,    N_LBUFFER, NULL,             "line-buffered", "use line buffering" },
240    { OP_NODATA,    N_LOFFSETS, NULL,            "line-offsets",  "output line numbers and offsets, not text" },    { OP_NODATA,    N_LOFFSETS, NULL,            "line-offsets",  "output line numbers and offsets, not text" },
241    { OP_STRING,    N_LOCALE, &locale,           "locale=locale", "use the named locale" },    { OP_STRING,    N_LOCALE, &locale,           "locale=locale", "use the named locale" },
242      { OP_NUMBER,    N_M_LIMIT,&match_limit,      "match-limit=number", "set PCRE match limit option" },
243      { OP_NUMBER,    N_M_LIMIT_REC,&match_limit_recursion, "recursion-limit=number", "set PCRE match recursion limit option" },
244    { OP_NODATA,    'M',      NULL,              "multiline",     "run in multiline mode" },    { OP_NODATA,    'M',      NULL,              "multiline",     "run in multiline mode" },
245    { OP_STRING,    'N',      &newline,          "newline=type",  "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" },    { OP_STRING,    'N',      &newline,          "newline=type",  "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" },
246    { OP_NODATA,    'n',      NULL,              "line-number",   "print line number with output lines" },    { OP_NODATA,    'n',      NULL,              "line-number",   "print line number with output lines" },
# Line 410  dir = (directory_type *) malloc(sizeof(* Line 418  dir = (directory_type *) malloc(sizeof(*
418  if ((pattern == NULL) || (dir == NULL))  if ((pattern == NULL) || (dir == NULL))
419    {    {
420    fprintf(stderr, "pcregrep: malloc failed\n");    fprintf(stderr, "pcregrep: malloc failed\n");
421    exit(2);    pcregrep_exit(2);
422    }    }
423  memcpy(pattern, filename, len);  memcpy(pattern, filename, len);
424  memcpy(&(pattern[len]), "\\*", 3);  memcpy(&(pattern[len]), "\\*", 3);
# Line 548  return sys_errlist[n]; Line 556  return sys_errlist[n];
556    
557    
558  /*************************************************  /*************************************************
559    *         Exit from the program                  *
560    *************************************************/
561    
562    /* If there has been a resource error, give a suitable message.
563    
564    Argument:  the return code
565    Returns:   does not return
566    */
567    
568    static void
569    pcregrep_exit(int rc)
570    {
571    if (resource_error)
572      {
573      fprintf(stderr, "pcregrep: Error %d or %d means that a resource limit "
574        "was exceeded.\n", PCRE_ERROR_MATCHLIMIT, PCRE_ERROR_RECURSIONLIMIT);
575      fprintf(stderr, "pcregrep: Check your regex for nested unlimited loops.\n");
576      }
577    
578    exit(rc);
579    }
580    
581    
582    
583    /*************************************************
584  *            Read one line of input              *  *            Read one line of input              *
585  *************************************************/  *************************************************/
586    
# Line 908  static BOOL Line 941  static BOOL
941  match_patterns(char *matchptr, size_t length, int *offsets, int *mrc)  match_patterns(char *matchptr, size_t length, int *offsets, int *mrc)
942  {  {
943  int i;  int i;
944    size_t slen = length;
945    const char *msg = "this text:\n\n";
946    if (slen > 200)
947      {
948      slen = 200;
949      msg = "text that starts:\n\n";
950      }
951  for (i = 0; i < pattern_count; i++)  for (i = 0; i < pattern_count; i++)
952    {    {
953    *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, 0,
954      PCRE_NOTEMPTY, offsets, OFFSET_SIZE);      PCRE_NOTEMPTY, offsets, OFFSET_SIZE);
955    if (*mrc >= 0) return TRUE;    if (*mrc >= 0) return TRUE;
956    if (*mrc == PCRE_ERROR_NOMATCH) continue;    if (*mrc == PCRE_ERROR_NOMATCH) continue;
957    fprintf(stderr, "pcregrep: pcre_exec() error %d while matching ", *mrc);    fprintf(stderr, "pcregrep: pcre_exec() gave error %d while matching ", *mrc);
958    if (pattern_count > 1) fprintf(stderr, "pattern number %d to ", i+1);    if (pattern_count > 1) fprintf(stderr, "pattern number %d to ", i+1);
959    fprintf(stderr, "this text:\n");    fprintf(stderr, "%s", msg);
960    FWRITE(matchptr, 1, length, stderr);   /* In case binary zero included */    FWRITE(matchptr, 1, slen, stderr);   /* In case binary zero included */
961    fprintf(stderr, "\n");    fprintf(stderr, "\n\n");
962    if (error_count == 0 &&    if (*mrc == PCRE_ERROR_MATCHLIMIT || *mrc == PCRE_ERROR_RECURSIONLIMIT)
963        (*mrc == PCRE_ERROR_MATCHLIMIT || *mrc == PCRE_ERROR_RECURSIONLIMIT))      resource_error = TRUE;
     {  
     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");  
     }  
964    if (error_count++ > 20)    if (error_count++ > 20)
965      {      {
966      fprintf(stderr, "pcregrep: too many errors - abandoned\n");      fprintf(stderr, "pcregrep: Too many errors - abandoned.\n");
967      exit(2);      pcregrep_exit(2);
968      }      }
969    return invert;    /* No more matching; don't show the line again */    return invert;    /* No more matching; don't show the line again */
970    }    }
# Line 1069  while (ptr < endptr) Line 1104  while (ptr < endptr)
1104            ptr = malloc(newlen + 1);            ptr = malloc(newlen + 1);
1105            if (!ptr) {            if (!ptr) {
1106                    printf("out of memory");                    printf("out of memory");
1107                    exit(2);                    pcregrep_exit(2);
1108            }            }
1109            endptr = ptr;            endptr = ptr;
1110            strcpy(endptr, jfriedl_prefix); endptr += strlen(jfriedl_prefix);            strcpy(endptr, jfriedl_prefix); endptr += strlen(jfriedl_prefix);
# Line 1765  handle_option(int letter, int options) Line 1800  handle_option(int letter, int options)
1800  switch(letter)  switch(letter)
1801    {    {
1802    case N_FOFFSETS: file_offsets = TRUE; break;    case N_FOFFSETS: file_offsets = TRUE; break;
1803    case N_HELP: help(); exit(0);    case N_HELP: help(); pcregrep_exit(0);
1804    case N_LOFFSETS: line_offsets = number = TRUE; break;    case N_LOFFSETS: line_offsets = number = TRUE; break;
1805    case N_LBUFFER: line_buffered = TRUE; break;    case N_LBUFFER: line_buffered = TRUE; break;
1806    case 'c': count_only = TRUE; break;    case 'c': count_only = TRUE; break;
# Line 1788  switch(letter) Line 1823  switch(letter)
1823    
1824    case 'V':    case 'V':
1825    fprintf(stderr, "pcregrep version %s\n", pcre_version());    fprintf(stderr, "pcregrep version %s\n", pcre_version());
1826    exit(0);    pcregrep_exit(0);
1827    break;    break;
1828    
1829    default:    default:
1830    fprintf(stderr, "pcregrep: Unknown option -%c\n", letter);    fprintf(stderr, "pcregrep: Unknown option -%c\n", letter);
1831    exit(usage(2));    pcregrep_exit(usage(2));
1832    }    }
1833    
1834  return options;  return options;
# Line 1989  for (i = 1; i < argc; i++) Line 2024  for (i = 1; i < argc; i++)
2024    if (argv[i][1] == 0)    if (argv[i][1] == 0)
2025      {      {
2026      if (pattern_filename != NULL || pattern_count > 0) break;      if (pattern_filename != NULL || pattern_count > 0) break;
2027        else exit(usage(2));        else pcregrep_exit(usage(2));
2028      }      }
2029    
2030    /* Handle a long name option, or -- to terminate the options */    /* Handle a long name option, or -- to terminate the options */
# Line 2080  for (i = 1; i < argc; i++) Line 2115  for (i = 1; i < argc; i++)
2115      if (op->one_char == 0)      if (op->one_char == 0)
2116        {        {
2117        fprintf(stderr, "pcregrep: Unknown option %s\n", argv[i]);        fprintf(stderr, "pcregrep: Unknown option %s\n", argv[i]);
2118        exit(usage(2));        pcregrep_exit(usage(2));
2119        }        }
2120      }      }
2121    
# Line 2122  for (i = 1; i < argc; i++) Line 2157  for (i = 1; i < argc; i++)
2157          {          {
2158          fprintf(stderr, "pcregrep: Unknown option letter '%c' in \"%s\"\n",          fprintf(stderr, "pcregrep: Unknown option letter '%c' in \"%s\"\n",
2159            *s, argv[i]);            *s, argv[i]);
2160          exit(usage(2));          pcregrep_exit(usage(2));
2161          }          }
2162        if (op->type != OP_NODATA || s[1] == 0)        if (op->type != OP_NODATA || s[1] == 0)
2163          {          {
# Line 2172  for (i = 1; i < argc; i++) Line 2207  for (i = 1; i < argc; i++)
2207      if (i >= argc - 1 || longopwasequals)      if (i >= argc - 1 || longopwasequals)
2208        {        {
2209        fprintf(stderr, "pcregrep: Data missing after %s\n", argv[i]);        fprintf(stderr, "pcregrep: Data missing after %s\n", argv[i]);
2210        exit(usage(2));        pcregrep_exit(usage(2));
2211        }        }
2212      option_data = argv[++i];      option_data = argv[++i];
2213      }      }
# Line 2203  for (i = 1; i < argc; i++) Line 2238  for (i = 1; i < argc; i++)
2238    
2239    else    else
2240      {      {
2241      int n = 0;      unsigned long int n = 0;
2242      char *endptr = option_data;      char *endptr = option_data;
2243      while (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++;      while (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++;
2244      while (isdigit((unsigned char)(*endptr)))      while (isdigit((unsigned char)(*endptr)))
# Line 2221  for (i = 1; i < argc; i++) Line 2256  for (i = 1; i < argc; i++)
2256        else        else
2257          fprintf(stderr, "pcregrep: Malformed number \"%s\" after -%c\n",          fprintf(stderr, "pcregrep: Malformed number \"%s\" after -%c\n",
2258            option_data, op->one_char);            option_data, op->one_char);
2259        exit(usage(2));        pcregrep_exit(usage(2));
2260        }        }
2261      *((int *)op->dataptr) = n;      *((int *)op->dataptr) = n;
2262      }      }
# Line 2244  if ((only_matching && (file_offsets || l Line 2279  if ((only_matching && (file_offsets || l
2279    {    {
2280    fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets "    fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets "
2281      "and/or --line-offsets\n");      "and/or --line-offsets\n");
2282    exit(usage(2));    pcregrep_exit(usage(2));
2283    }    }
2284    
2285  if (file_offsets || line_offsets) only_matching = TRUE;  if (file_offsets || line_offsets) only_matching = TRUE;
# Line 2455  for (j = 0; j < pattern_count; j++) Line 2490  for (j = 0; j < pattern_count; j++)
2490      }      }
2491    hint_count++;    hint_count++;
2492    }    }
2493    
2494    /* If --match-limit or --recursion-limit was set, put the value(s) into the
2495    pcre_extra block for each pattern. */
2496    
2497    if (match_limit > 0 || match_limit_recursion > 0)
2498      {
2499      for (j = 0; j < pattern_count; j++)
2500        {
2501        if (hints_list[j] == NULL)
2502          {
2503          hints_list[j] = malloc(sizeof(pcre_extra));
2504          if (hints_list[j] == NULL)
2505            {
2506            fprintf(stderr, "pcregrep: malloc failed\n");
2507            pcregrep_exit(2);
2508            }
2509          }
2510        if (match_limit > 0)
2511          {
2512          hints_list[j]->flags |= PCRE_EXTRA_MATCH_LIMIT;
2513          hints_list[j]->match_limit = match_limit;
2514          }
2515        if (match_limit_recursion > 0)
2516          {
2517          hints_list[j]->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
2518          hints_list[j]->match_limit_recursion = match_limit_recursion;
2519          }
2520        }
2521      }
2522    
2523  /* If there are include or exclude patterns, compile them. */  /* If there are include or exclude patterns, compile them. */
2524    
# Line 2537  if (pattern_list != NULL) Line 2601  if (pattern_list != NULL)
2601    }    }
2602  if (hints_list != NULL)  if (hints_list != NULL)
2603    {    {
2604    for (i = 0; i < hint_count; i++) free(hints_list[i]);    for (i = 0; i < hint_count; i++)
2605        {
2606        if (hints_list[i] != NULL) free(hints_list[i]);
2607        }
2608    free(hints_list);    free(hints_list);
2609    }    }
2610  return rc;  pcregrep_exit(rc);
2611    
2612  EXIT2:  EXIT2:
2613  rc = 2;  rc = 2;

Legend:
Removed from v.560  
changed lines
  Added in v.561

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12