/[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 53 by nigel, Sat Feb 24 21:39:42 2007 UTC revision 63 by nigel, Sat Feb 24 21:40:03 2007 UTC
# Line 3  Line 3 
3  *************************************************/  *************************************************/
4    
5  /* This is a grep program that uses the PCRE regular expression library to do  /* This is a grep program that uses the PCRE regular expression library to do
6  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
7    directories. */
8    
9  #include <ctype.h>  #include <ctype.h>
10  #include <stdio.h>  #include <stdio.h>
# Line 18  its pattern matching. On a Unix system i Line 19  its pattern matching. On a Unix system i
19    
20  typedef int BOOL;  typedef int BOOL;
21    
22  #define VERSION "2.0 01-Aug-2001"  #define VERSION "3.0 14-Jan-2003"
23  #define MAX_PATTERN_COUNT 100  #define MAX_PATTERN_COUNT 100
24    
25    
# Line 57  static option_item optionlist[] = { Line 58  static option_item optionlist[] = {
58    { 'n', "line-number",  "print line number with output lines" },    { 'n', "line-number",  "print line number with output lines" },
59    { 'r', "recursive",    "recursively scan sub-directories" },    { 'r', "recursive",    "recursively scan sub-directories" },
60    { 's', "no-messages",  "suppress error messages" },    { 's', "no-messages",  "suppress error messages" },
61      { 'u', "utf-8",        "use UTF-8 mode" },
62    { 'V', "version",      "print version information and exit" },    { 'V', "version",      "print version information and exit" },
63    { 'v', "invert-match", "select non-matching lines" },    { 'v', "invert-match", "select non-matching lines" },
64    { 'x', "line-regex",   "force PATTERN to match only whole lines" },    { 'x', "line-regex",   "force PATTERN to match only whole lines" },
# Line 70  static option_item optionlist[] = { Line 72  static option_item optionlist[] = {
72  *************************************************/  *************************************************/
73    
74  /* These functions are defined so that they can be made system specific,  /* These functions are defined so that they can be made system specific,
75  although at present the only ones are for Unix, and for "no directory recursion  although at present the only ones are for Unix, Win32, and for "no directory
76  support". */  recursion support". */
77    
78    
79  /************* Directory scanning in Unix ***********/  /************* Directory scanning in Unix ***********/
# Line 118  closedir(dir); Line 120  closedir(dir);
120  }  }
121    
122    
123  #else  /************* Directory scanning in Win32 ***********/
124    
125    /* I (Philip Hazel) have no means of testing this code. It was contributed by
126    Lionel Fourquaux. */
127    
128    
129    #elif HAVE_WIN32API
130    
131    #ifndef STRICT
132    # define STRICT
133    #endif
134    #ifndef WIN32_LEAN_AND_MEAN
135    # define WIN32_LEAN_AND_MEAN
136    #endif
137    #include <windows.h>
138    
139    typedef struct directory_type
140    {
141    HANDLE handle;
142    BOOL first;
143    WIN32_FIND_DATA data;
144    } directory_type;
145    
146    int
147    isdirectory(char *filename)
148    {
149    DWORD attr = GetFileAttributes(filename);
150    if (attr == INVALID_FILE_ATTRIBUTES)
151      return 0;
152    return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) ? '/' : 0;
153    }
154    
155    directory_type *
156    opendirectory(char *filename)
157    {
158    size_t len;
159    char *pattern;
160    directory_type *dir;
161    DWORD err;
162    len = strlen(filename);
163    pattern = (char *) malloc(len + 3);
164    dir = (directory_type *) malloc(sizeof(*dir));
165    if ((pattern == NULL) || (dir == NULL))
166      {
167      fprintf(stderr, "pcregrep: malloc failed\n");
168      exit(2);
169      }
170    memcpy(pattern, filename, len);
171    memcpy(&(pattern[len]), "\\*", 3);
172    dir->handle = FindFirstFile(pattern, &(dir->data));
173    if (dir->handle != INVALID_HANDLE_VALUE)
174      {
175      free(pattern);
176      dir->first = TRUE;
177      return dir;
178      }
179    err = GetLastError();
180    free(pattern);
181    free(dir);
182    errno = (err == ERROR_ACCESS_DENIED) ? EACCES : ENOENT;
183    return NULL;
184    }
185    
186    char *
187    readdirectory(directory_type *dir)
188    {
189    for (;;)
190      {
191      if (!dir->first)
192        {
193        if (!FindNextFile(dir->handle, &(dir->data)))
194          return NULL;
195        }
196      else
197        {
198        dir->first = FALSE;
199        }
200      if (strcmp(dir->data.cFileName, ".") != 0 && strcmp(dir->data.cFileName, "..") != 0)
201        return dir->data.cFileName;
202      }
203    #ifndef _MSC_VER
204    return NULL;   /* Keep compiler happy; never executed */
205    #endif
206    }
207    
208    void
209    closedirectory(directory_type *dir)
210    {
211    FindClose(dir->handle);
212    free(dir);
213    }
214    
215    
216  /************* Directory scanning when we can't do it ***********/  /************* Directory scanning when we can't do it ***********/
217    
218  /* The type is void, and apart from isdirectory(), the functions do nothing. */  /* The type is void, and apart from isdirectory(), the functions do nothing. */
219    
220    #else
221    
222  typedef void directory_type;  typedef void directory_type;
223    
224  int isdirectory(char *filename) { return FALSE; }  int isdirectory(char *filename) { return FALSE; }
# Line 262  if ((sep = isdirectory(filename)) != 0 & Line 356  if ((sep = isdirectory(filename)) != 0 &
356    }    }
357    
358  /* If the file is not a directory, or we are not recursing, scan it. If this is  /* If the file is not a directory, or we are not recursing, scan it. If this is
359  the first and only argument at top level, we don't show the file name.  the first and only argument at top level, we don't show the file name (unless
360  Otherwise, control is via the show_filenames variable. */  we are only showing the file name). Otherwise, control is via the
361    show_filenames variable. */
362    
363  in = fopen(filename, "r");  in = fopen(filename, "r");
364  if (in == NULL)  if (in == NULL)
# Line 272  if (in == NULL) Line 367  if (in == NULL)
367    return 2;    return 2;
368    }    }
369    
370  rc = pcregrep(in, (show_filenames && !only_one_at_top)? filename : NULL);  rc = pcregrep(in, (filenames_only || (show_filenames && !only_one_at_top))?
371      filename : NULL);
372  fclose(in);  fclose(in);
373  return rc;  return rc;
374  }  }
# Line 287  return rc; Line 383  return rc;
383  static int  static int
384  usage(int rc)  usage(int rc)
385  {  {
386  fprintf(stderr, "Usage: pcregrep [-Vcfhilnrsvx] [long-options] pattern [file] ...\n");  fprintf(stderr, "Usage: pcregrep [-Vcfhilnrsvx] [long-options] [pattern] [file1 file2 ...]\n");
387  fprintf(stderr, "Type `pcregrep --help' for more information.\n");  fprintf(stderr, "Type `pcregrep --help' for more information.\n");
388  return rc;  return rc;
389  }  }
# Line 304  help(void) Line 400  help(void)
400  {  {
401  option_item *op;  option_item *op;
402    
403  printf("Usage: pcregrep [OPTION]... PATTERN [FILE] ...\n");  printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n");
404  printf("Search for PATTERN in each FILE or standard input.\n");  printf("Search for PATTERN in each FILE or standard input.\n");
405    printf("PATTERN must be present if -f is not used.\n");
406  printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n");  printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n");
407    
408  printf("Options:\n");  printf("Options:\n");
# Line 350  switch(letter) Line 447  switch(letter)
447    case 'n': number = TRUE; break;    case 'n': number = TRUE; break;
448    case 'r': recurse = TRUE; break;    case 'r': recurse = TRUE; break;
449    case 's': silent = TRUE; break;    case 's': silent = TRUE; break;
450      case 'u': options |= PCRE_UTF8; break;
451    case 'v': invert = TRUE; break;    case 'v': invert = TRUE; break;
452    case 'x': whole_lines = TRUE; options |= PCRE_ANCHORED; break;    case 'x': whole_lines = TRUE; options |= PCRE_ANCHORED; break;
453    
# Line 390  for (i = 1; i < argc; i++) Line 488  for (i = 1; i < argc; i++)
488    {    {
489    if (argv[i][0] != '-') break;    if (argv[i][0] != '-') break;
490    
491      /* Missing options */
492    
493      if (argv[i][1] == 0) exit(usage(2));
494    
495    /* Long name options */    /* Long name options */
496    
497    if (argv[i][1] == '-')    if (argv[i][1] == '-')
# Line 492  if (pattern_filename != NULL) Line 594  if (pattern_filename != NULL)
594    
595  else  else
596    {    {
597    if (i >= argc) return usage(0);    if (i >= argc) return usage(2);
598    pattern_list[0] = pcre_compile(argv[i++], options, &error, &errptr, NULL);    pattern_list[0] = pcre_compile(argv[i++], options, &error, &errptr, NULL);
599    if (pattern_list[0] == NULL)    if (pattern_list[0] == NULL)
600      {      {

Legend:
Removed from v.53  
changed lines
  Added in v.63

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12