From c8cb607ab7e12e185e86a8b23d413b7f9536f24c Mon Sep 17 00:00:00 2001 From: nigel Date: Sat, 24 Feb 2007 21:40:03 +0000 Subject: Load pcre-4.0 into code/trunk. git-svn-id: svn://vcs.exim.org/pcre/code/trunk@63 2f5784b3-3f2a-0410-8824-cb99058d5e15 --- pcregrep.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 11 deletions(-) (limited to 'pcregrep.c') diff --git a/pcregrep.c b/pcregrep.c index b50ed07..a86fefb 100644 --- a/pcregrep.c +++ b/pcregrep.c @@ -3,7 +3,8 @@ *************************************************/ /* This is a grep program that uses the PCRE regular expression library to do -its pattern matching. On a Unix system it can recurse into directories. */ +its pattern matching. On a Unix or Win32 system it can recurse into +directories. */ #include #include @@ -18,7 +19,7 @@ its pattern matching. On a Unix system it can recurse into directories. */ typedef int BOOL; -#define VERSION "2.0 01-Aug-2001" +#define VERSION "3.0 14-Jan-2003" #define MAX_PATTERN_COUNT 100 @@ -57,6 +58,7 @@ static option_item optionlist[] = { { 'n', "line-number", "print line number with output lines" }, { 'r', "recursive", "recursively scan sub-directories" }, { 's', "no-messages", "suppress error messages" }, + { 'u', "utf-8", "use UTF-8 mode" }, { 'V', "version", "print version information and exit" }, { 'v', "invert-match", "select non-matching lines" }, { 'x', "line-regex", "force PATTERN to match only whole lines" }, @@ -70,8 +72,8 @@ static option_item optionlist[] = { *************************************************/ /* These functions are defined so that they can be made system specific, -although at present the only ones are for Unix, and for "no directory recursion -support". */ +although at present the only ones are for Unix, Win32, and for "no directory +recursion support". */ /************* Directory scanning in Unix ***********/ @@ -118,13 +120,105 @@ closedir(dir); } -#else +/************* Directory scanning in Win32 ***********/ + +/* I (Philip Hazel) have no means of testing this code. It was contributed by +Lionel Fourquaux. */ + + +#elif HAVE_WIN32API + +#ifndef STRICT +# define STRICT +#endif +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include + +typedef struct directory_type +{ +HANDLE handle; +BOOL first; +WIN32_FIND_DATA data; +} directory_type; + +int +isdirectory(char *filename) +{ +DWORD attr = GetFileAttributes(filename); +if (attr == INVALID_FILE_ATTRIBUTES) + return 0; +return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) ? '/' : 0; +} + +directory_type * +opendirectory(char *filename) +{ +size_t len; +char *pattern; +directory_type *dir; +DWORD err; +len = strlen(filename); +pattern = (char *) malloc(len + 3); +dir = (directory_type *) malloc(sizeof(*dir)); +if ((pattern == NULL) || (dir == NULL)) + { + fprintf(stderr, "pcregrep: malloc failed\n"); + exit(2); + } +memcpy(pattern, filename, len); +memcpy(&(pattern[len]), "\\*", 3); +dir->handle = FindFirstFile(pattern, &(dir->data)); +if (dir->handle != INVALID_HANDLE_VALUE) + { + free(pattern); + dir->first = TRUE; + return dir; + } +err = GetLastError(); +free(pattern); +free(dir); +errno = (err == ERROR_ACCESS_DENIED) ? EACCES : ENOENT; +return NULL; +} + +char * +readdirectory(directory_type *dir) +{ +for (;;) + { + if (!dir->first) + { + if (!FindNextFile(dir->handle, &(dir->data))) + return NULL; + } + else + { + dir->first = FALSE; + } + if (strcmp(dir->data.cFileName, ".") != 0 && strcmp(dir->data.cFileName, "..") != 0) + return dir->data.cFileName; + } +#ifndef _MSC_VER +return NULL; /* Keep compiler happy; never executed */ +#endif +} + +void +closedirectory(directory_type *dir) +{ +FindClose(dir->handle); +free(dir); +} /************* Directory scanning when we can't do it ***********/ /* The type is void, and apart from isdirectory(), the functions do nothing. */ +#else + typedef void directory_type; int isdirectory(char *filename) { return FALSE; } @@ -262,8 +356,9 @@ if ((sep = isdirectory(filename)) != 0 && recurse) } /* If the file is not a directory, or we are not recursing, scan it. If this is -the first and only argument at top level, we don't show the file name. -Otherwise, control is via the show_filenames variable. */ +the first and only argument at top level, we don't show the file name (unless +we are only showing the file name). Otherwise, control is via the +show_filenames variable. */ in = fopen(filename, "r"); if (in == NULL) @@ -272,7 +367,8 @@ if (in == NULL) return 2; } -rc = pcregrep(in, (show_filenames && !only_one_at_top)? filename : NULL); +rc = pcregrep(in, (filenames_only || (show_filenames && !only_one_at_top))? + filename : NULL); fclose(in); return rc; } @@ -287,7 +383,7 @@ return rc; static int usage(int rc) { -fprintf(stderr, "Usage: pcregrep [-Vcfhilnrsvx] [long-options] pattern [file] ...\n"); +fprintf(stderr, "Usage: pcregrep [-Vcfhilnrsvx] [long-options] [pattern] [file1 file2 ...]\n"); fprintf(stderr, "Type `pcregrep --help' for more information.\n"); return rc; } @@ -304,8 +400,9 @@ help(void) { option_item *op; -printf("Usage: pcregrep [OPTION]... PATTERN [FILE] ...\n"); +printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n"); printf("Search for PATTERN in each FILE or standard input.\n"); +printf("PATTERN must be present if -f is not used.\n"); printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n"); printf("Options:\n"); @@ -350,6 +447,7 @@ switch(letter) case 'n': number = TRUE; break; case 'r': recurse = TRUE; break; case 's': silent = TRUE; break; + case 'u': options |= PCRE_UTF8; break; case 'v': invert = TRUE; break; case 'x': whole_lines = TRUE; options |= PCRE_ANCHORED; break; @@ -390,6 +488,10 @@ for (i = 1; i < argc; i++) { if (argv[i][0] != '-') break; + /* Missing options */ + + if (argv[i][1] == 0) exit(usage(2)); + /* Long name options */ if (argv[i][1] == '-') @@ -492,7 +594,7 @@ if (pattern_filename != NULL) else { - if (i >= argc) return usage(0); + if (i >= argc) return usage(2); pattern_list[0] = pcre_compile(argv[i++], options, &error, &errptr, NULL); if (pattern_list[0] == NULL) { -- cgit v1.2.1