2011-01-01  Juan Manuel Guerrero <juan.guerrero@gmx.de>

	* RunGrepTest:  Convert CRLF to NL before comparing test results with
	reference templates.


2010-12-31  Juan Manuel Guerrero <juan.guerrero@gmx.de>

	* pcregrep.c [__DJGPP__]:  New macro HAVE_LFN_SUPPORT.  For DJGPP it
	checks if LFN support is available or not.  For all other systems it
	returns true.  New macro CANONICALIZE_PATH.  For DJGPP it changes all
	backslashes to slashes in path name.  NO-OP for all other systems.
	[__DJGPP__]:  Include <fcntl.h> for O_BINARY definition.  On systems
	that do not provide a definition for O_BINARY set it to 0.
	[__DJGPP__]:  Include djgpp_sgr_support.c for DJGPP specific ansi.sys-
	less color support.
	(help) [SUPPORT_LIBZ, SUPPORT_LIBBZ2]:  Use HAVE_LFN_SUPPORT to control
	the kind of help message.
	(grep_or_recurse) [SUPPORT_LIBZ, SUPPORT_LIBBZ2, HAVE_LFN_SUPPORT]:  If
	only SFN support availble allow also ".*gz" and ".**z" as extensions of
	gzip compressed files.  If only SFN support availble allow also ".*bz"
	as extension of bzip2 compressed files.
	(is_file_tty) [O_BINARY]:  If stdin is not connected to a file, it is
	switched into O_TEXT mode.
	(isdirectory) [__DJGPP__]:  Use access() instead of stat() to determinate
	if given path is an existing directory.
	(isregfile) [__DJGPP__]:  Use access() instead of stat() to determinate
	if given filename is a regular file.


2010-12-30  Juan Manuel Guerrero <juan.guerrero@gmx.de>

	* pcretest.c [__DJGPP__]:  New macro SET_BINARY to set file modes.  For
	systems other than DJGPP and WIN32 this is a no-op.
	(main):  Use SET_BINARY to change file mode.
	(main) [__DJGPP__]:  Changing stack size using -S option is not
	supported by DJGPP.

	* djgpp_sgr_support.c: (msdos_screen_write, djgpp_grep_startup,
	screen_puts, restore_blink_bit) [__DJGPP__]:  New functions to support
	colorization without requiring ANSI.SYS driver (or its work-alike) to
	be loaded.  
	(msdos_screen_write):  Added support to decode and execute erase part
	of the line to the right escape sequence (ESC-[K), that is used to
	initialize and finish SGR escape sequences.

	* RunGrepTest:  Replace '\r\n' by '\n' because DJGPP's port of printf
	prints a newline for every \r and for every \n.

	* testdata/grepoutput:  Add (ENOENT) string to error messages of test
	case 16 and 33.

	* doc/pcregrep.1:  DJGPP specific info added.

	* doc/pcregrep.txt:  DJGPP specific info added.








diff -aprNU5 pcre-8.11.orig/RunGrepTest pcre-8.11/RunGrepTest
--- pcre-8.11.orig/RunGrepTest	2010-11-16 17:44:06 +0000
+++ pcre-8.11/RunGrepTest	2011-01-01 16:11:16 +0000
@@ -327,10 +327,11 @@ echo "---------------------------- Test
 (cd $srcdir; $valgrind $pcregrep --only-matching=2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry
 echo "RC=$?" >>testtry
 
 # Now compare the results.
 
+dtou testtry # DOS/DJGPP specific.
 $cf $srcdir/testdata/grepoutput testtry
 if [ $? != 0 ] ; then exit 1; fi
 
 
 # These tests require UTF-8 support
@@ -362,28 +363,28 @@ fi
 # starts with a hyphen.
 
 echo "Testing pcregrep newline settings"
 printf "abc\rdef\r\nghi\njkl" >testNinput
 
-printf "%c--------------------------- Test N1 ------------------------------\r\n" - >testtry
+printf "%c--------------------------- Test N1 ------------------------------\n" - >testtry
 $valgrind $pcregrep -n -N CR "^(abc|def|ghi|jkl)" testNinput >>testtry
 
-printf "%c--------------------------- Test N2 ------------------------------\r\n" - >>testtry
+printf "%c--------------------------- Test N2 ------------------------------\n" - >>testtry
 $valgrind $pcregrep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinput >>testtry
 
-printf "%c--------------------------- Test N3 ------------------------------\r\n" - >>testtry
+printf "%c--------------------------- Test N3 ------------------------------\n" - >>testtry
 pattern=`printf 'def\rjkl'`
 $valgrind $pcregrep -n --newline=cr -F "$pattern" testNinput >>testtry
 
-printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>testtry
+printf "%c--------------------------- Test N4 ------------------------------\n" - >>testtry
 pattern=`printf 'xxx\r\njkl'`
 $valgrind $pcregrep -n --newline=crlf -F "$pattern" testNinput >>testtry
 
-printf "%c--------------------------- Test N5 ------------------------------\r\n" - >>testtry
+printf "%c--------------------------- Test N5 ------------------------------\n" - >>testtry
 $valgrind $pcregrep -n --newline=any "^(abc|def|ghi|jkl)" testNinput >>testtry
 
-printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtry
+printf "%c--------------------------- Test N6 ------------------------------\n" - >>testtry
 $valgrind $pcregrep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinput >>testtry
 
 $cf $srcdir/testdata/grepoutputN testtry
 if [ $? != 0 ] ; then exit 1; fi
 
diff -aprNU5 pcre-8.11.orig/djgpp_sgr_support.c pcre-8.11/djgpp_sgr_support.c
--- pcre-8.11.orig/djgpp_sgr_support.c	1970-01-01 00:00:00 +0000
+++ pcre-8.11/djgpp_sgr_support.c	2011-01-01 15:47:48 +0000
@@ -0,0 +1,355 @@
+/*
+   djgpp_sgr_support.c
+   Copyright (C) 2010 DJ Delorie, see COPYING.DJ for details.
+*/
+
+
+/* Messy DOS/DJGPP-specific code for emulating a Posix terminal driver
+   wrt SGR (a.k.a. ANSI) color escape sequences.
+
+   This has several aspects:
+
+     * Redirecting output with ANSI color commands to direct screen
+       writes.
+
+*/
+
+#include <config.h>
+
+/*  Screen write redirection.  We need this to support colorization
+    without requiring ANSI.SYS driver (or its work-alike) to be loaded.
+
+    This function uses the DJGPP filesystem extensions mechanism.  It is
+    installed as a handler for handle-based functions (read/write/close)
+    for the standard output (but actually only handles writes, only if
+    the standard output is connected to the terminal, and only if user
+    asked for colorization).  When a buffer is written to the screen by
+    low-level functions of the DJGPP C library, our handler will be
+    called.  For any request that doesn't require colored screen writes
+    we return a zero to the caller, in which case the caller will handle
+    the output in the usual way (by eventually calling DOS).
+
+    When colorization *is* required, the buffer is written directly to
+    the screen while converting the ANSI escape sequences into calls to
+    DJGPP conio functions which change text attributes.  A non-zero value is
+    then returned to the caller to signal that the output has been handled.
+*/
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <unistd.h>
+#include <conio.h>
+#include <sys/fsext.h>
+#include <go32.h> /* for `_dos_ds' */
+#include <sys/farptr.h>
+
+static int norm_blink = -1, cur_blink = -1;
+static unsigned char norm_attr = 0, cur_attr = 0;
+static int isatty_stdout = -1;
+static size_t leftover = 0;
+
+/* Restore the BIOS blinking bit to its original value.  Called at exit.  */
+static void
+restore_blink_bit(void)
+{
+  if (cur_blink != norm_blink)
+  {
+    if (norm_blink > 0)
+      blinkvideo ();
+    else
+      intensevideo ();
+  }
+}
+
+/* Write a buffer to the screen video memory.  This expands the TAB
+   characters to the appropriate number of spaces, and also does TRT
+   with null characters and other non-printable characters, if
+   any.  */
+static void
+screen_puts (char *buf, char *buf_end)
+{
+  register char *p = buf, *q = p;
+  int row, col;
+  unsigned char c;
+
+  while (p < buf_end)
+  {
+    if (*p < ' ')
+    {
+      switch (*p)
+      {
+      case '\b':
+      case '\r':
+      case '\n':
+        /* nothing: cputs already does TRT with these */
+        break;
+      case '\t':
+        *p = '\0';
+        cputs (q);
+        ScreenGetCursor(&row, &col);
+        for (cputs (" "), col += 1; col % 8; col++)
+          cputs (" ");
+        q = p + 1;
+        *p = '\t';
+        break;
+      default:
+        c = *p;
+        *p = '\0';
+        cputs (q);
+        cputs ("^");
+        putch (c | 0x40);
+        q = p + 1;
+        *p = c;
+        break;
+      }
+    }
+    p++;
+  }
+  /* Output whatever is left.  */
+  cputs (q);
+}
+
+#define ESC '\033'
+#define IS_SGR(s) (((s)[1] == '[') && ((s)[2] == 'm'))
+#define IS_EL(s)  (((s)[1] == '[') && ((s)[2] == 'K'))
+
+/* Screen writes redirector function.  */
+static int
+msdos_screen_write (__FSEXT_Fnumber func, int *retval, va_list rest_args)
+{
+  static char *cbuf = NULL;
+  static size_t cbuf_len = 0;
+  /* Only dark colors mentioned here, so that bold has visible effect.  */
+  static enum COLORS screen_color[] = {
+    BLACK,
+    RED,
+    GREEN,
+    BROWN,
+    BLUE,
+    MAGENTA,
+    CYAN,
+    LIGHTGRAY
+  };
+  char *anchor, *p_next;
+  unsigned char fg, bg;
+
+  int handle;
+  char *buf, *buf_end;
+  size_t buflen;
+
+  /* Avoid direct screen writes unless colorization was actually requested.
+     Otherwise, we will break programs that catch I/O from their children.  */
+  handle = va_arg (rest_args, int);
+  if (!do_colour || func != __FSEXT_write ||
+      !(handle == STDOUT_FILENO ? isatty_stdout : isatty (handle)))
+    return 0;
+
+  buf = va_arg(rest_args, char *);
+  if (!buf)
+  {
+    errno = EINVAL;
+    *retval = -1;
+    return 1;
+  }
+
+  /* Allocate a sufficiently large buffer to hold the output.  */
+  buflen = va_arg (rest_args, size_t);
+  if (!cbuf)
+  {
+    struct text_info txtinfo;
+
+    cbuf_len = buflen + 1;
+    cbuf = (char *)xmalloc (cbuf_len);
+    gettextinfo (&txtinfo);
+    norm_attr = txtinfo.attribute; /* save the original text attribute */
+    cur_attr = norm_attr;
+    /* Does it normally blink when bg has its 3rd bit set?  */
+    norm_blink = (_farpeekb (_dos_ds, 0x465) & 0x20) ? 1 : 0;
+    cur_blink = norm_blink;
+  }
+  else if (buflen >= cbuf_len)
+  {
+    cbuf_len = buflen + 1 + leftover;
+    cbuf = (char *)xrealloc (cbuf, cbuf_len);
+  }
+  memcpy (cbuf + leftover, buf, buflen);
+  buf_end = cbuf + buflen + leftover;
+  *buf_end = '\0';
+
+  /* Current text attributes are used as baseline.  */
+  fg = cur_attr & 15;
+  bg = (cur_attr >> 4) & 15;
+
+  /* Walk the buffer, writing text directly to video RAM,
+     changing color attributes when an escape sequence is seen.  */
+  for (anchor = p_next = cbuf; (p_next = memchr(p_next, ESC, buflen - (p_next - cbuf))) != 0;)
+  {
+    char *p = p_next;
+
+    /* If some chars seen since the last escape sequence,
+       write it out to the screen using current text attributes.  */
+    if (p > anchor)
+    {
+      *p = '\0'; /* `cputs' needs ASCIIZ string */
+      screen_puts (anchor, p);
+      *p = ESC; /* restore the ESC character */
+      anchor = p;
+    }
+
+    /* Handle the null escape sequence (ESC-[m), which is used to
+       restore the original color. */
+    if (IS_SGR(p))
+    {
+      textattr (norm_attr);
+      p += 3;
+      anchor = p_next = p;
+      continue;
+    }
+
+    /* Handle the erase in line to the right escape sequence (ESC-[K). */
+    if (IS_EL(p))
+    {
+      clreol();
+      p += 3;
+      anchor = p_next = p;
+      continue;
+    }
+
+    if (p[1] == '[') /* "Esc-[" sequence */
+    {
+      p += 2; /* get past "Esc-[" sequence */
+      p_next = p;
+      while (*p != 'm') /* `m' ends the escape sequence */
+      {
+        char *q;
+        long code = strtol (p, &q, 10);
+
+        if (!*q)
+        {
+          /* Incomplete escape sequence.  Remember the part
+             we've seen for the next time.  */
+          leftover = q - anchor;
+          if (leftover >= cbuf_len)
+          {
+            cbuf_len += 1 + leftover;
+            cbuf = (char *)xrealloc (cbuf, cbuf_len);
+          }
+          strcpy (cbuf, anchor);
+          *retval = buflen; /* that's a lie, but we have to! */
+          return 1;
+        }
+
+        /* 
+           Sanity checks:
+
+           q > p unless p doesn't point to a number;
+           SGR codes supported by ANSI.SYS are between 0 and 49;
+           Each SGR code ends with a `;' or an `m'.
+
+           If any of the above is violated, we just ignore the bogon.
+        */
+        if (q == p || code > 49 || code < 0 || (*q != 'm' && *q != ';'))
+        {
+          p_next = q;
+          break;
+        }
+        if (*q == ';') /* more codes to follow */
+        q++;
+
+        /* Convert ANSI codes to color fore- and background.  */
+        switch (code)
+        {
+        case 0: /* all attributes off */
+          fg = norm_attr & 15;
+          bg = (norm_attr >> 4) & 15;
+          break;
+        case 1: /* intensity on */
+          fg |= 8;
+          break;
+        case 4: /* underline on */
+          fg |= 8; /* we can't, so make it bold instead */
+          break;
+        case 5: /* blink */
+          if (cur_blink != 1)
+          {
+            blinkvideo (); /* ensure we are'nt in bright bg mode */
+            cur_blink = 1;
+          }
+          bg |= 8;
+          break;
+        case 7: /* reverse video */
+          {
+            unsigned char t = fg;
+            fg = bg;
+            bg = t;
+
+            /* If it was blinking before, let it blink after.  */
+            if (fg & 8)
+              bg |= 8;
+
+            /* If the fg was bold, let the background be bold.  */
+            if ((t & 8) && cur_blink != 0)
+            {
+              intensevideo ();
+              cur_blink = 0;
+            }
+          }
+          break;
+        case 8: /* concealed on */
+          fg = (bg & 7) | 8; /* make fg be like bg, only bright */
+          break;
+        case 30: case 31: case 32: case 33: /* foreground color */
+        case 34: case 35: case 36: case 37:
+          fg = (fg & 8) | (screen_color[code - 30] & 15);
+          break;
+        case 40: case 41: case 42: case 43: /* background color */
+        case 44: case 45: case 46: case 47:
+          bg = (bg & 8) | (screen_color[code - 40] & 15);
+          break;
+        case 39: /* default fg */
+          fg = norm_attr & 15;
+          break;
+        case 49:
+          bg = (norm_attr >> 4) & 15;
+          break;
+        default:
+          p_next = q; /* ignore unknown codes */
+          break;
+        }
+        p = q;
+      } /* while loop */
+
+      if (*p == 'm' && p > p_next)
+      {
+        /* They don't *really* want it invisible, do they?  */
+        if (fg == (bg & 7))
+          fg |= 8; /* make it concealed instead */
+
+        /* Construct the text attribute and set it.  */
+        cur_attr = (bg << 4) | fg;
+        textattr (cur_attr);
+        p_next = anchor = p + 1;
+      }
+      else
+        break;
+    }
+    else
+      p_next++;
+  }  /* for loop */
+
+  /* Output what's left in the buffer.  */
+  screen_puts (anchor, buf_end);
+  leftover = 0;
+  *retval = buflen;
+  return 1;
+}
+
+/* This is called before `main' to install our STDOUT redirector.  */
+static void __attribute__((constructor))
+djgpp_grep_startup (void)
+{
+  __FSEXT_set_function (STDOUT_FILENO, msdos_screen_write);
+  isatty_stdout = isatty (STDOUT_FILENO);
+  atexit (restore_blink_bit);
+}
diff -aprNU5 pcre-8.11.orig/doc/pcregrep.1 pcre-8.11/doc/pcregrep.1
--- pcre-8.11.orig/doc/pcregrep.1	2010-11-24 17:38:32 +0000
+++ pcre-8.11/doc/pcregrep.1	2011-01-01 15:47:48 +0000
@@ -83,10 +83,18 @@ It is possible to compile \fBpcregrep\fP
 \fBlibbz2\fP to read files whose names end in \fB.gz\fP or \fB.bz2\fP,
 respectively. You can find out whether your binary has support for one or both
 of these file types by running it with the \fB--help\fP option. If the
 appropriate support is not present, files are treated as plain text. The
 standard input is always so treated.
+The DJGPP port of \fBpcregrep\fP detects at runtime if LFN support is
+available or not. If only SFN support is available then apart of the
+\fB.bz2\fP extension for \fBbzip2\fP compressed files the \fB.*bz\fP
+extension also will be accepted as valid extension. The star stands
+for any valid character. If only SFN support is available then both
+\fB.*gz\fP and \fB.**z\fP extensions will be accepted together with
+the \fB.gz\fP extension as valid extension for files compressed with
+\fBlibz\fP. Here also a star stands for any valid character.
 .
 .SH OPTIONS
 .rs
 .sp
 The order in which some of the options appear can affect the output. For
diff -aprNU5 pcre-8.11.orig/doc/pcregrep.txt pcre-8.11/doc/pcregrep.txt
--- pcre-8.11.orig/doc/pcregrep.txt	2010-12-10 11:36:38 +0000
+++ pcre-8.11/doc/pcregrep.txt	2011-01-01 15:47:48 +0000
@@ -87,10 +87,17 @@ SUPPORT FOR COMPRESSED FILES
        read  files  whose names end in .gz or .bz2, respectively. You can find
        out whether your binary has support for one or both of these file types
        by running it with the --help option. If the appropriate support is not
        present, files are treated as plain text. The standard input is  always
        so treated.
+       The DJGPP port of pcregrep detects at runtime if LFN support is available
+       or not. If only SFN support is available then apart of the .bz2 extension
+       for bzip2 compressed files the .*bz extension also will be accepted as
+       valid extension. The star stands for any valid character. If only SFN
+       support is available then both .*gz and .**z extensions will be accepted
+       together with the .gz extension as valid extension for files compressed
+       with libz. Here also a star stands for any valid character.
 
 
 OPTIONS
 
        The  order  in  which some of the options appear can affect the output.
diff -aprNU5 pcre-8.11.orig/pcregrep.c pcre-8.11/pcregrep.c
--- pcre-8.11.orig/pcregrep.c	2010-11-24 17:38:32 +0000
+++ pcre-8.11/pcregrep.c	2011-01-01 15:47:48 +0000
@@ -53,10 +53,24 @@ POSSIBILITY OF SUCH DAMAGE.
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 
+#ifndef O_RDONLY
+#include <fcntl.h>
+#else
+#include <sys/fcntl.h>
+#endif
+
+#ifndef O_BINARY
+# ifdef _O_BINARY
+#  define O_BINARY _O_BINARY
+# else
+#  define O_BINARY 0
+# endif
+#endif /* O_BINARY */
+
 #ifdef SUPPORT_LIBZ
 #include <zlib.h>
 #endif
 
 #ifdef SUPPORT_LIBBZ2
@@ -110,10 +124,29 @@ Unfortunately, casting to (void) does no
 this, we use a macro that compiles a fudge. Oddly, this does not also seem to
 apply to fprintf(). */
 
 #define FWRITE(a,b,c,d) if (fwrite(a,b,c,d)) {}
 
+#ifdef __DJGPP__
+# include <libc/unconst.h>
+# define CANONICALIZE_PATH(path)             \
+  ({                                         \
+      if ((path))                            \
+      {                                      \
+        char *_p = unconst((path), char *);  \
+        for (; *_p; _p++)                    \
+          if (*_p == '\\')                   \
+            *_p = '/';                       \
+      }                                      \
+      (path);                                \
+  })
+# define HAVE_LFN_SUPPORT(name)   ((pathconf((name), _PC_NAME_MAX) > 12) ? TRUE : FALSE)
+#else
+# define CANONICALIZE_PATH(path)  (path)
+# define HAVE_LFN_SUPPORT(name)   (TRUE)
+#endif
+
 
 
 /*************************************************
 *               Global variables                 *
 *************************************************/
@@ -313,14 +346,24 @@ although at present the only ones are fo
 typedef DIR directory_type;
 
 static int
 isdirectory(char *filename)
 {
+#ifdef __DJGPP__
+  /*
+   *  Computation of stat is very expensive.
+   *  To determinate if FILENAME is an existing
+   *  directory, access on DOS platforms is
+   *  mostly a fast system call.
+   */
+  return (access(filename, D_OK) == 0) ? '/' : 0;
+#else
 struct stat statbuf;
 if (stat(filename, &statbuf) < 0)
   return 0;        /* In the expectation that opening as a file will fail */
 return ((statbuf.st_mode & S_IFMT) == S_IFDIR)? '/' : 0;
+#endif
 }
 
 static directory_type *
 opendirectory(char *filename)
 {
@@ -350,14 +393,24 @@ closedir(dir);
 /************* Test for regular file in Unix **********/
 
 static int
 isregfile(char *filename)
 {
+#ifdef __DJGPP__
+  /*
+   *  Computation of stat is very expensive.
+   *  To determinate if FILENAME is an existing
+   *  regular file, access on DOS platforms is
+   *  mostly a fast system call.
+   */
+  return access(filename, D_OK);  /* Any file that is not a dir is treated as regular file.  */
+#else
 struct stat statbuf;
 if (stat(filename, &statbuf) < 0)
   return 1;        /* In the expectation that opening as a file will fail */
 return (statbuf.st_mode & S_IFMT) == S_IFREG;
+#endif
 }
 
 
 /************* Test for a terminal in Unix **********/
 
@@ -368,14 +421,26 @@ return isatty(fileno(stdout));
 }
 
 static BOOL
 is_file_tty(FILE *f)
 {
+#if O_BINARY
+int fd = fileno(f);
+return isatty(fd) ? setmode(fd, O_TEXT), TRUE : FALSE;
+#else
 return isatty(fileno(f));
+#endif
 }
 
 
+/************* DJGPP specific SGR support ***********/
+
+#ifdef __DJGPP__
+#include "djgpp_sgr_support.c"
+#endif
+
+
 /************* Directory scanning in Win32 ***********/
 
 /* I (Philip Hazel) have no means of testing this code. It was contributed by
 Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES
 when it did not exist. David Byron added a patch that moved the #include of
@@ -1646,10 +1711,26 @@ if (pathlen > 3 && strcmp(pathname + pat
     }
   handle = (void *)ingz;
   frtype = FR_LIBZ;
   }
 else
+if (!HAVE_LFN_SUPPORT(pathname))
+{
+  if (pathlen > 4 && pathname[pathlen - 4] == '.' && strcmp(pathname + pathlen - 2, "gz") == 0 || strcmp(pathname + pathlen - 1, "z") == 0)
+  {
+    ingz = gzopen(pathname, "rb");
+    if (ingz == NULL)
+    {
+      if (!silent)
+        fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname, strerror(errno));
+      return 2;
+    }
+    handle = (void *)ingz;
+    frtype = FR_LIBZ;
+  }
+}
+else
 #endif
 
 /* Otherwise open with bz2lib if it is supported and the name ends with .bz2. */
 
 #ifdef SUPPORT_LIBBZ2
@@ -1658,10 +1739,20 @@ if (pathlen > 4 && strcmp(pathname + pat
   inbz2 = BZ2_bzopen(pathname, "rb");
   handle = (void *)inbz2;
   frtype = FR_LIBBZ2;
   }
 else
+if (!HAVE_LFN_SUPPORT(pathname))
+{
+  if (pathlen > 4 && pathname[pathlen - 4] == '.' && strcmp(pathname + pathlen - 2, "bz") == 0)
+  {
+   inbz2 = BZ2_bzopen(pathname, "rb");
+   handle = (void *)inbz2;
+   frtype = FR_LIBBZ2;
+  }
+}
+else
 #endif
 
 /* Otherwise use plain fopen(). The label is so that we can come back here if
 an attempt to read a .bz2 file indicates that it really is a plain file. */
 
@@ -1769,15 +1860,21 @@ printf("Usage: pcregrep [OPTION]... [PAT
 printf("Search for PATTERN in each FILE or standard input.\n");
 printf("PATTERN must be present if neither -e nor -f is used.\n");
 printf("\"-\" can be used as a file name to mean STDIN.\n");
 
 #ifdef SUPPORT_LIBZ
-printf("Files whose names end in .gz are read using zlib.\n");
+if (HAVE_LFN_SUPPORT("./"))
+  printf("Files whose names end in .gz are read using zlib.\n");
+else
+  printf("Files whose names end in .gz or .*gz or .**z are read using zlib\nwhere '*' stands for any valid letter.\n");
 #endif
 
 #ifdef SUPPORT_LIBBZ2
-printf("Files whose names end in .bz2 are read using bzlib2.\n");
+if (HAVE_LFN_SUPPORT("./"))
+  printf("Files whose names end in .bz2 are read using bzlib2.\n");
+else
+  printf("Files whose names end in .bz2 or .*bz are read using bzlib2\nwhere '*' stands for any valid letter.\n");
 #endif
 
 #if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2
 printf("Other files and the standard input are read as plain files.\n\n");
 #else
@@ -2635,11 +2732,11 @@ otherwise forced. */
 
 only_one_at_top = i == argc - 1;   /* Catch initial value of i */
 
 for (; i < argc; i++)
   {
-  int frc = grep_or_recurse(argv[i], dee_action == dee_RECURSE,
+  int frc = grep_or_recurse(CANONICALIZE_PATH(argv[i]), dee_action == dee_RECURSE,
     only_one_at_top);
   if (frc > 1) rc = frc;
     else if (frc == 0 && rc == 1) rc = 0;
   }
 
diff -aprNU5 pcre-8.11.orig/pcretest.c pcre-8.11/pcretest.c
--- pcre-8.11.orig/pcretest.c	2010-11-26 11:11:24 +0000
+++ pcre-8.11/pcretest.c	2011-01-01 15:47:48 +0000
@@ -63,37 +63,65 @@ environments, so it was added for releas
 makes no difference on Unix-like systems.) Later I was told that it is wrong
 for the input on Windows. I've now abstracted the modes into two macros that
 are set here, to make it easier to fiddle with them, and removed "b" from the
 input mode under Windows. */
 
-#if defined(_WIN32) || defined(WIN32)
+#if defined(_WIN32) || defined(WIN32) || defined(__DJGPP__)
 #include <io.h>                /* For _setmode() */
 #include <fcntl.h>             /* For _O_BINARY */
 #define INPUT_MODE   "r"
 #define OUTPUT_MODE  "wb"
 
+#ifndef O_BINARY
+#define O_BINARY _O_BINARY
+
 #ifndef isatty
 #define isatty _isatty         /* This is what Windows calls them, I'm told, */
 #endif                         /* though in some environments they seem to   */
                                /* be already defined, hence the #ifndefs.    */
 #ifndef fileno
 #define fileno _fileno
 #endif
 
+#ifndef setmode
+#define setmode _setmode
+#endif
+#endif
+
 /* A user sent this fix for Borland Builder 5 under Windows. */
 
 #ifdef __BORLANDC__
 #define _setmode(handle, mode) setmode(handle, mode)
 #endif
 
+/*
+  Switch file from O_TEXT mode into O_BINARY mode.
+  Do never switch console input into binary mode, doing so will attempt
+  to read from the console with no echo and no way to signal EOF or even
+  interrupt the program (since special characters like ^Z and ^C are not
+  special in binary mode).  For all practical purposes, a program which
+  does that, wedges the machine.
+  If both stdin and stdout are the console device, don't switch stdout
+  into binary mode either, since that will switch the console device
+  into raw mode, with the same consequences as described above.
+*/
+#define SET_BINARY_MODE(file)  \
+  do {                         \
+    int fd = fileno(file);     \
+    if (!isatty(fd))           \
+      setmode(fd, O_BINARY);   \
+  } while (0)
+
 /* Not Windows */
 
 #else
 #include <sys/time.h>          /* These two includes are needed */
 #include <sys/resource.h>      /* for setrlimit(). */
 #define INPUT_MODE   "rb"
 #define OUTPUT_MODE  "wb"
+/* On POSIX there is no difference between O_TEXT mode and O_BINARY mode of a file. */
+#define SET_BINARY_MODE(file)   (void)0
 #endif
 
 
 /* We have to include pcre_internal.h because we need the internal info for
 displaying the results of pcre_study() and we also need to know about the
@@ -1219,13 +1247,11 @@ outfile = stdout;
 /* The following  _setmode() stuff is some Windows magic that tells its runtime
 library to translate CRLF into a single LF character. At least, that's what
 I've been told: never having used Windows I take this all on trust. Originally
 it set 0x8000, but then I was advised that _O_BINARY was better. */
 
-#if defined(_WIN32) || defined(WIN32)
-_setmode( _fileno( stdout ), _O_BINARY );
-#endif
+SET_BINARY_MODE(stdout);
 
 /* Scan options */
 
 while (argc > 1 && argv[op][0] == '-')
   {
@@ -1264,11 +1290,11 @@ while (argc > 1 && argv[op][0] == '-')
     }
   else if (strcmp(argv[op], "-S") == 0 && argc > 2 &&
       ((stack_size = get_value((unsigned char *)argv[op+1], &endptr)),
         *endptr == 0))
     {
-#if defined(_WIN32) || defined(WIN32)
+#if defined(_WIN32) || defined(WIN32) || defined(__DJGPP__)
     printf("PCRE: -S not supported on this OS\n");
     exit(1);
 #else
     int rc;
     struct rlimit rlim;
diff -aprNU5 pcre-8.11.orig/testdata/grepoutput pcre-8.11/testdata/grepoutput
--- pcre-8.11.orig/testdata/grepoutput	2010-10-31 17:40:02 +0000
+++ pcre-8.11/testdata/grepoutput	2011-01-01 15:47:48 +0000
@@ -100,11 +100,11 @@ RC=0
 RC=0
 ---------------------------- Test 15 -----------------------------
 pcregrep: Error in command-line regex at offset 4: nothing to repeat
 RC=2
 ---------------------------- Test 16 -----------------------------
-pcregrep: Failed to open ./testdata/nonexistfile: No such file or directory
+pcregrep: Failed to open ./testdata/nonexistfile: No such file or directory (ENOENT)
 RC=2
 ---------------------------- Test 17 -----------------------------
 features should be added at the end, because some of the tests involve the
 output of line numbers, and we don't want these to change.
 RC=0
@@ -363,11 +363,11 @@ RC=0
 RC=0
 ---------------------------- Test 32 -----------------------------
 ./testdata/grepinputx
 RC=0
 ---------------------------- Test 33 -----------------------------
-pcregrep: Failed to open ./testdata/grepnonexist: No such file or directory
+pcregrep: Failed to open ./testdata/grepnonexist: No such file or directory (ENOENT)
 RC=2
 ---------------------------- Test 34 -----------------------------
 RC=2
 ---------------------------- Test 35 -----------------------------
 ./testdata/grepinputx
