diff options
Diffstat (limited to 'ext/pcre/pcrelib/pgrep.c')
| -rw-r--r-- | ext/pcre/pcrelib/pgrep.c | 225 | 
1 files changed, 225 insertions, 0 deletions
diff --git a/ext/pcre/pcrelib/pgrep.c b/ext/pcre/pcrelib/pgrep.c new file mode 100644 index 0000000000..ad1b87eae9 --- /dev/null +++ b/ext/pcre/pcrelib/pgrep.c @@ -0,0 +1,225 @@ +/************************************************* +*               PCRE grep program                * +*************************************************/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include "config.h" +#include "pcre.h" + +#define FALSE 0 +#define TRUE 1 + +typedef int BOOL; + + + +/************************************************* +*               Global variables                 * +*************************************************/ + +static pcre *pattern; +static pcre_extra *hints; + +static BOOL count_only = FALSE; +static BOOL filenames_only = FALSE; +static BOOL invert = FALSE; +static BOOL number = FALSE; +static BOOL silent = FALSE; +static BOOL whole_lines = FALSE; + + + +#if ! HAVE_STRERROR +/************************************************* +*     Provide strerror() for non-ANSI libraries  * +*************************************************/ + +/* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() +in their libraries, but can provide the same facility by this simple +alternative function. */ + +extern int   sys_nerr; +extern char *sys_errlist[]; + +char * +strerror(int n) +{ +if (n < 0 || n >= sys_nerr) return "unknown error number"; +return sys_errlist[n]; +} +#endif /* HAVE_STRERROR */ + + + +/************************************************* +*              Grep an individual file           * +*************************************************/ + +static int +pgrep(FILE *in, char *name) +{ +int rc = 1; +int linenumber = 0; +int count = 0; +int offsets[99]; +char buffer[BUFSIZ]; + +while (fgets(buffer, sizeof(buffer), in) != NULL) +  { +  BOOL match; +  int length = (int)strlen(buffer); +  if (length > 0 && buffer[length-1] == '\n') buffer[--length] = 0; +  linenumber++; + +  match = pcre_exec(pattern, hints, buffer, length, 0, 0, offsets, 99) >= 0; +  if (match && whole_lines && offsets[1] != length) match = FALSE; + +  if (match != invert) +    { +    if (count_only) count++; + +    else if (filenames_only) +      { +      fprintf(stdout, "%s\n", (name == NULL)? "<stdin>" : name); +      return 0; +      } + +    else if (silent) return 0; + +    else +      { +      if (name != NULL) fprintf(stdout, "%s:", name); +      if (number) fprintf(stdout, "%d:", linenumber); +      fprintf(stdout, "%s\n", buffer); +      } + +    rc = 0; +    } +  } + +if (count_only) +  { +  if (name != NULL) fprintf(stdout, "%s:", name); +  fprintf(stdout, "%d\n", count); +  } + +return rc; +} + + + + +/************************************************* +*                Usage function                  * +*************************************************/ + +static int +usage(int rc) +{ +fprintf(stderr, "Usage: pgrep [-Vchilnsvx] pattern [file] ...\n"); +return rc; +} + + + + +/************************************************* +*                Main program                    * +*************************************************/ + +int +main(int argc, char **argv) +{ +int i; +int rc = 1; +int options = 0; +int errptr; +const char *error; +BOOL filenames = TRUE; + +/* Process the options */ + +for (i = 1; i < argc; i++) +  { +  char *s; +  if (argv[i][0] != '-') break; +  s = argv[i] + 1; +  while (*s != 0) +    { +    switch (*s++) +      { +      case 'c': count_only = TRUE; break; +      case 'h': filenames = FALSE; break; +      case 'i': options |= PCRE_CASELESS; break; +      case 'l': filenames_only = TRUE; +      case 'n': number = TRUE; break; +      case 's': silent = TRUE; break; +      case 'v': invert = TRUE; break; +      case 'x': whole_lines = TRUE; options |= PCRE_ANCHORED; break; + +      case 'V': +      fprintf(stderr, "PCRE version %s\n", pcre_version()); +      break; + +      default: +      fprintf(stderr, "pgrep: unknown option %c\n", s[-1]); +      return usage(2); +      } +    } +  } + +/* There must be at least a regexp argument */ + +if (i >= argc) return usage(0); + +/* Compile the regular expression. */ + +pattern = pcre_compile(argv[i++], options, &error, &errptr, NULL); +if (pattern == NULL) +  { +  fprintf(stderr, "pgrep: error in regex at offset %d: %s\n", errptr, error); +  return 2; +  } + +/* Study the regular expression, as we will be running it may times */ + +hints = pcre_study(pattern, 0, &error); +if (error != NULL) +  { +  fprintf(stderr, "pgrep: error while studing regex: %s\n", error); +  return 2; +  } + +/* If there are no further arguments, do the business on stdin and exit */ + +if (i >= argc) return pgrep(stdin, NULL); + +/* Otherwise, work through the remaining arguments as files. If there is only +one, don't give its name on the output. */ + +if (i == argc - 1) filenames = FALSE; +if (filenames_only) filenames = TRUE; + +for (; i < argc; i++) +  { +  FILE *in = fopen(argv[i], "r"); +  if (in == NULL) +    { +    fprintf(stderr, "%s: failed to open: %s\n", argv[i], strerror(errno)); +    rc = 2; +    } +  else +    { +    int frc = pgrep(in, filenames? argv[i] : NULL); +    if (frc == 0 && rc == 1) rc = 0; +    fclose(in); +    } +  } + +return rc; +} + +/* End */  | 
