You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by pg...@apache.org on 2007/11/26 17:50:09 UTC

svn commit: r598339 [29/37] - in /httpd/httpd/vendor/pcre/current: ./ doc/ doc/html/ testdata/

Added: httpd/httpd/vendor/pcre/current/pcre_ord2utf8.c
URL: http://svn.apache.org/viewvc/httpd/httpd/vendor/pcre/current/pcre_ord2utf8.c?rev=598339&view=auto
==============================================================================
--- httpd/httpd/vendor/pcre/current/pcre_ord2utf8.c (added)
+++ httpd/httpd/vendor/pcre/current/pcre_ord2utf8.c Mon Nov 26 08:49:53 2007
@@ -0,0 +1,85 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2007 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This file contains a private PCRE function that converts an ordinal
+character value into a UTF8 string. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+*       Convert character value to UTF-8         *
+*************************************************/
+
+/* This function takes an integer value in the range 0 - 0x7fffffff
+and encodes it as a UTF-8 character in 0 to 6 bytes.
+
+Arguments:
+  cvalue     the character value
+  buffer     pointer to buffer for result - at least 6 bytes long
+
+Returns:     number of characters placed in the buffer
+*/
+
+int
+_pcre_ord2utf8(int cvalue, uschar *buffer)
+{
+#ifdef SUPPORT_UTF8
+register int i, j;
+for (i = 0; i < _pcre_utf8_table1_size; i++)
+  if (cvalue <= _pcre_utf8_table1[i]) break;
+buffer += i;
+for (j = i; j > 0; j--)
+ {
+ *buffer-- = 0x80 | (cvalue & 0x3f);
+ cvalue >>= 6;
+ }
+*buffer = _pcre_utf8_table2[i] | cvalue;
+return i + 1;
+#else
+return 0;   /* Keep compiler happy; this function won't ever be */
+#endif      /* called when SUPPORT_UTF8 is not defined. */
+}
+
+/* End of pcre_ord2utf8.c */

Added: httpd/httpd/vendor/pcre/current/pcre_printint.src
URL: http://svn.apache.org/viewvc/httpd/httpd/vendor/pcre/current/pcre_printint.src?rev=598339&view=auto
==============================================================================
--- httpd/httpd/vendor/pcre/current/pcre_printint.src (added)
+++ httpd/httpd/vendor/pcre/current/pcre_printint.src Mon Nov 26 08:49:53 2007
@@ -0,0 +1,512 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2007 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains a PCRE private debugging function for printing out the
+internal form of a compiled regular expression, along with some supporting
+local functions. This source file is used in two places:
+
+(1) It is #included by pcre_compile.c when it is compiled in debugging mode
+(DEBUG defined in pcre_internal.h). It is not included in production compiles.
+
+(2) It is always #included by pcretest.c, which can be asked to print out a
+compiled regex for debugging purposes. */
+
+
+/* Macro that decides whether a character should be output as a literal or in
+hexadecimal. We don't use isprint() because that can vary from system to system
+(even without the use of locales) and we want the output always to be the same,
+for testing purposes. This macro is used in pcretest as well as in this file. */
+
+#define PRINTABLE(c) ((c) >= 32 && (c) < 127)
+
+/* The table of operator names. */
+
+static const char *OP_names[] = { OP_NAME_LIST };
+
+
+
+/*************************************************
+*       Print single- or multi-byte character    *
+*************************************************/
+
+static int
+print_char(FILE *f, uschar *ptr, BOOL utf8)
+{
+int c = *ptr;
+
+#ifndef SUPPORT_UTF8
+utf8 = utf8;  /* Avoid compiler warning */
+if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
+return 0;
+
+#else
+if (!utf8 || (c & 0xc0) != 0xc0)
+  {
+  if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
+  return 0;
+  }
+else
+  {
+  int i;
+  int a = _pcre_utf8_table4[c & 0x3f];  /* Number of additional bytes */
+  int s = 6*a;
+  c = (c & _pcre_utf8_table3[a]) << s;
+  for (i = 1; i <= a; i++)
+    {
+    /* This is a check for malformed UTF-8; it should only occur if the sanity
+    check has been turned off. Rather than swallow random bytes, just stop if
+    we hit a bad one. Print it with \X instead of \x as an indication. */
+
+    if ((ptr[i] & 0xc0) != 0x80)
+      {
+      fprintf(f, "\\X{%x}", c);
+      return i - 1;
+      }
+
+    /* The byte is OK */
+
+    s -= 6;
+    c |= (ptr[i] & 0x3f) << s;
+    }
+  if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c);
+  return a;
+  }
+#endif
+}
+
+
+
+/*************************************************
+*          Find Unicode property name            *
+*************************************************/
+
+static const char *
+get_ucpname(int ptype, int pvalue)
+{
+#ifdef SUPPORT_UCP
+int i;
+for (i = _pcre_utt_size - 1; i >= 0; i--)
+  {
+  if (ptype == _pcre_utt[i].type && pvalue == _pcre_utt[i].value) break;
+  }
+return (i >= 0)? _pcre_utt_names + _pcre_utt[i].name_offset : "??";
+#else
+/* It gets harder and harder to shut off unwanted compiler warnings. */
+ptype = ptype * pvalue;
+return (ptype == pvalue)? "??" : "??";
+#endif
+}
+
+
+
+/*************************************************
+*         Print compiled regex                   *
+*************************************************/
+
+/* Make this function work for a regex with integers either byte order.
+However, we assume that what we are passed is a compiled regex. The
+print_lengths flag controls whether offsets and lengths of items are printed.
+They can be turned off from pcretest so that automatic tests on bytecode can be
+written that do not depend on the value of LINK_SIZE. */
+
+static void
+pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
+{
+real_pcre *re = (real_pcre *)external_re;
+uschar *codestart, *code;
+BOOL utf8;
+
+unsigned int options = re->options;
+int offset = re->name_table_offset;
+int count = re->name_count;
+int size = re->name_entry_size;
+
+if (re->magic_number != MAGIC_NUMBER)
+  {
+  offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff);
+  count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff);
+  size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff);
+  options = ((options << 24) & 0xff000000) |
+            ((options <<  8) & 0x00ff0000) |
+            ((options >>  8) & 0x0000ff00) |
+            ((options >> 24) & 0x000000ff);
+  }
+
+code = codestart = (uschar *)re + offset + count * size;
+utf8 = (options & PCRE_UTF8) != 0;
+
+for(;;)
+  {
+  uschar *ccode;
+  int c;
+  int extra = 0;
+
+  if (print_lengths)
+    fprintf(f, "%3d ", (int)(code - codestart));
+  else
+    fprintf(f, "    ");
+
+  switch(*code)
+    {
+    case OP_END:
+    fprintf(f, "    %s\n", OP_names[*code]);
+    fprintf(f, "------------------------------------------------------------------\n");
+    return;
+
+    case OP_OPT:
+    fprintf(f, " %.2x %s", code[1], OP_names[*code]);
+    break;
+
+    case OP_CHAR:
+    fprintf(f, "    ");
+    do
+      {
+      code++;
+      code += 1 + print_char(f, code, utf8);
+      }
+    while (*code == OP_CHAR);
+    fprintf(f, "\n");
+    continue;
+
+    case OP_CHARNC:
+    fprintf(f, " NC ");
+    do
+      {
+      code++;
+      code += 1 + print_char(f, code, utf8);
+      }
+    while (*code == OP_CHARNC);
+    fprintf(f, "\n");
+    continue;
+
+    case OP_CBRA:
+    case OP_SCBRA:
+    if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
+      else fprintf(f, "    ");
+    fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE));
+    break;
+
+    case OP_BRA:
+    case OP_SBRA:
+    case OP_KETRMAX:
+    case OP_KETRMIN:
+    case OP_ALT:
+    case OP_KET:
+    case OP_ASSERT:
+    case OP_ASSERT_NOT:
+    case OP_ASSERTBACK:
+    case OP_ASSERTBACK_NOT:
+    case OP_ONCE:
+    case OP_COND:
+    case OP_SCOND:
+    case OP_REVERSE:
+    if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
+      else fprintf(f, "    ");
+    fprintf(f, "%s", OP_names[*code]);
+    break;
+
+    case OP_CREF:
+    fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);
+    break;
+
+    case OP_RREF:
+    c = GET2(code, 1);
+    if (c == RREF_ANY)
+      fprintf(f, "    Cond recurse any");
+    else
+      fprintf(f, "    Cond recurse %d", c);
+    break;
+
+    case OP_DEF:
+    fprintf(f, "    Cond def");
+    break;
+
+    case OP_STAR:
+    case OP_MINSTAR:
+    case OP_POSSTAR:
+    case OP_PLUS:
+    case OP_MINPLUS:
+    case OP_POSPLUS:
+    case OP_QUERY:
+    case OP_MINQUERY:
+    case OP_POSQUERY:
+    case OP_TYPESTAR:
+    case OP_TYPEMINSTAR:
+    case OP_TYPEPOSSTAR:
+    case OP_TYPEPLUS:
+    case OP_TYPEMINPLUS:
+    case OP_TYPEPOSPLUS:
+    case OP_TYPEQUERY:
+    case OP_TYPEMINQUERY:
+    case OP_TYPEPOSQUERY:
+    fprintf(f, "    ");
+    if (*code >= OP_TYPESTAR)
+      {
+      fprintf(f, "%s", OP_names[code[1]]);
+      if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
+        {
+        fprintf(f, " %s ", get_ucpname(code[2], code[3]));
+        extra = 2;
+        }
+      }
+    else extra = print_char(f, code+1, utf8);
+    fprintf(f, "%s", OP_names[*code]);
+    break;
+
+    case OP_EXACT:
+    case OP_UPTO:
+    case OP_MINUPTO:
+    case OP_POSUPTO:
+    fprintf(f, "    ");
+    extra = print_char(f, code+3, utf8);
+    fprintf(f, "{");
+    if (*code != OP_EXACT) fprintf(f, "0,");
+    fprintf(f, "%d}", GET2(code,1));
+    if (*code == OP_MINUPTO) fprintf(f, "?");
+      else if (*code == OP_POSUPTO) fprintf(f, "+");
+    break;
+
+    case OP_TYPEEXACT:
+    case OP_TYPEUPTO:
+    case OP_TYPEMINUPTO:
+    case OP_TYPEPOSUPTO:
+    fprintf(f, "    %s", OP_names[code[3]]);
+    if (code[3] == OP_PROP || code[3] == OP_NOTPROP)
+      {
+      fprintf(f, " %s ", get_ucpname(code[4], code[5]));
+      extra = 2;
+      }
+    fprintf(f, "{");
+    if (*code != OP_TYPEEXACT) fprintf(f, "0,");
+    fprintf(f, "%d}", GET2(code,1));
+    if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
+      else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");
+    break;
+
+    case OP_NOT:
+    c = code[1];
+    if (PRINTABLE(c)) fprintf(f, "    [^%c]", c);
+      else fprintf(f, "    [^\\x%02x]", c);
+    break;
+
+    case OP_NOTSTAR:
+    case OP_NOTMINSTAR:
+    case OP_NOTPOSSTAR:
+    case OP_NOTPLUS:
+    case OP_NOTMINPLUS:
+    case OP_NOTPOSPLUS:
+    case OP_NOTQUERY:
+    case OP_NOTMINQUERY:
+    case OP_NOTPOSQUERY:
+    c = code[1];
+    if (PRINTABLE(c)) fprintf(f, "    [^%c]", c);
+      else fprintf(f, "    [^\\x%02x]", c);
+    fprintf(f, "%s", OP_names[*code]);
+    break;
+
+    case OP_NOTEXACT:
+    case OP_NOTUPTO:
+    case OP_NOTMINUPTO:
+    case OP_NOTPOSUPTO:
+    c = code[3];
+    if (PRINTABLE(c)) fprintf(f, "    [^%c]{", c);
+      else fprintf(f, "    [^\\x%02x]{", c);
+    if (*code != OP_NOTEXACT) fprintf(f, "0,");
+    fprintf(f, "%d}", GET2(code,1));
+    if (*code == OP_NOTMINUPTO) fprintf(f, "?");
+      else if (*code == OP_NOTPOSUPTO) fprintf(f, "+");
+    break;
+
+    case OP_RECURSE:
+    if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
+      else fprintf(f, "    ");
+    fprintf(f, "%s", OP_names[*code]);
+    break;
+
+    case OP_REF:
+    fprintf(f, "    \\%d", GET2(code,1));
+    ccode = code + _pcre_OP_lengths[*code];
+    goto CLASS_REF_REPEAT;
+
+    case OP_CALLOUT:
+    fprintf(f, "    %s %d %d %d", OP_names[*code], code[1], GET(code,2),
+      GET(code, 2 + LINK_SIZE));
+    break;
+
+    case OP_PROP:
+    case OP_NOTPROP:
+    fprintf(f, "    %s %s", OP_names[*code], get_ucpname(code[1], code[2]));
+    break;
+
+    /* OP_XCLASS can only occur in UTF-8 mode. However, there's no harm in
+    having this code always here, and it makes it less messy without all those
+    #ifdefs. */
+
+    case OP_CLASS:
+    case OP_NCLASS:
+    case OP_XCLASS:
+      {
+      int i, min, max;
+      BOOL printmap;
+
+      fprintf(f, "    [");
+
+      if (*code == OP_XCLASS)
+        {
+        extra = GET(code, 1);
+        ccode = code + LINK_SIZE + 1;
+        printmap = (*ccode & XCL_MAP) != 0;
+        if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^");
+        }
+      else
+        {
+        printmap = TRUE;
+        ccode = code + 1;
+        }
+
+      /* Print a bit map */
+
+      if (printmap)
+        {
+        for (i = 0; i < 256; i++)
+          {
+          if ((ccode[i/8] & (1 << (i&7))) != 0)
+            {
+            int j;
+            for (j = i+1; j < 256; j++)
+              if ((ccode[j/8] & (1 << (j&7))) == 0) break;
+            if (i == '-' || i == ']') fprintf(f, "\\");
+            if (PRINTABLE(i)) fprintf(f, "%c", i);
+              else fprintf(f, "\\x%02x", i);
+            if (--j > i)
+              {
+              if (j != i + 1) fprintf(f, "-");
+              if (j == '-' || j == ']') fprintf(f, "\\");
+              if (PRINTABLE(j)) fprintf(f, "%c", j);
+                else fprintf(f, "\\x%02x", j);
+              }
+            i = j;
+            }
+          }
+        ccode += 32;
+        }
+
+      /* For an XCLASS there is always some additional data */
+
+      if (*code == OP_XCLASS)
+        {
+        int ch;
+        while ((ch = *ccode++) != XCL_END)
+          {
+          if (ch == XCL_PROP)
+            {
+            int ptype = *ccode++;
+            int pvalue = *ccode++;
+            fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue));
+            }
+          else if (ch == XCL_NOTPROP)
+            {
+            int ptype = *ccode++;
+            int pvalue = *ccode++;
+            fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue));
+            }
+          else
+            {
+            ccode += 1 + print_char(f, ccode, TRUE);
+            if (ch == XCL_RANGE)
+              {
+              fprintf(f, "-");
+              ccode += 1 + print_char(f, ccode, TRUE);
+              }
+            }
+          }
+        }
+
+      /* Indicate a non-UTF8 class which was created by negation */
+
+      fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
+
+      /* Handle repeats after a class or a back reference */
+
+      CLASS_REF_REPEAT:
+      switch(*ccode)
+        {
+        case OP_CRSTAR:
+        case OP_CRMINSTAR:
+        case OP_CRPLUS:
+        case OP_CRMINPLUS:
+        case OP_CRQUERY:
+        case OP_CRMINQUERY:
+        fprintf(f, "%s", OP_names[*ccode]);
+        extra += _pcre_OP_lengths[*ccode];
+        break;
+
+        case OP_CRRANGE:
+        case OP_CRMINRANGE:
+        min = GET2(ccode,1);
+        max = GET2(ccode,3);
+        if (max == 0) fprintf(f, "{%d,}", min);
+        else fprintf(f, "{%d,%d}", min, max);
+        if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
+        extra += _pcre_OP_lengths[*ccode];
+        break;
+
+        /* Do nothing if it's not a repeat; this code stops picky compilers
+        warning about the lack of a default code path. */
+
+        default:
+        break;
+        }
+      }
+    break;
+
+    /* Anything else is just an item with no data*/
+
+    default:
+    fprintf(f, "    %s", OP_names[*code]);
+    break;
+    }
+
+  code += _pcre_OP_lengths[*code] + extra;
+  fprintf(f, "\n");
+  }
+}
+
+/* End of pcre_printint.src */

Added: httpd/httpd/vendor/pcre/current/pcre_refcount.c
URL: http://svn.apache.org/viewvc/httpd/httpd/vendor/pcre/current/pcre_refcount.c?rev=598339&view=auto
==============================================================================
--- httpd/httpd/vendor/pcre/current/pcre_refcount.c (added)
+++ httpd/httpd/vendor/pcre/current/pcre_refcount.c Mon Nov 26 08:49:53 2007
@@ -0,0 +1,82 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2007 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_refcount(), which is an
+auxiliary function that can be used to maintain a reference count in a compiled
+pattern data block. This might be helpful in applications where the block is
+shared by different users. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+*           Maintain reference count             *
+*************************************************/
+
+/* The reference count is a 16-bit field, initialized to zero. It is not
+possible to transfer a non-zero count from one host to a different host that
+has a different byte order - though I can't see why anyone in their right mind
+would ever want to do that!
+
+Arguments:
+  argument_re   points to compiled code
+  adjust        value to add to the count
+
+Returns:        the (possibly updated) count value (a non-negative number), or
+                a negative error number
+*/
+
+PCRE_EXP_DEFN int
+pcre_refcount(pcre *argument_re, int adjust)
+{
+real_pcre *re = (real_pcre *)argument_re;
+if (re == NULL) return PCRE_ERROR_NULL;
+re->ref_count = (-adjust > re->ref_count)? 0 :
+                (adjust + re->ref_count > 65535)? 65535 :
+                re->ref_count + adjust;
+return re->ref_count;
+}
+
+/* End of pcre_refcount.c */

Added: httpd/httpd/vendor/pcre/current/pcre_scanner.cc
URL: http://svn.apache.org/viewvc/httpd/httpd/vendor/pcre/current/pcre_scanner.cc?rev=598339&view=auto
==============================================================================
--- httpd/httpd/vendor/pcre/current/pcre_scanner.cc (added)
+++ httpd/httpd/vendor/pcre/current/pcre_scanner.cc Mon Nov 26 08:49:53 2007
@@ -0,0 +1,199 @@
+// Copyright (c) 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Sanjay Ghemawat
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <vector>
+#include <assert.h>
+
+#include "pcrecpp_internal.h"
+#include "pcre_scanner.h"
+
+using std::vector;
+
+namespace pcrecpp {
+
+Scanner::Scanner()
+  : data_(),
+    input_(data_),
+    skip_(NULL),
+    should_skip_(false),
+    skip_repeat_(false),
+    save_comments_(false),
+    comments_(NULL),
+    comments_offset_(0) {
+}
+
+Scanner::Scanner(const string& in)
+  : data_(in),
+    input_(data_),
+    skip_(NULL),
+    should_skip_(false),
+    skip_repeat_(false),
+    save_comments_(false),
+    comments_(NULL),
+    comments_offset_(0) {
+}
+
+Scanner::~Scanner() {
+  delete skip_;
+  delete comments_;
+}
+
+void Scanner::SetSkipExpression(const char* re) {
+  delete skip_;
+  if (re != NULL) {
+    skip_ = new RE(re);
+    should_skip_ = true;
+    skip_repeat_ = true;
+    ConsumeSkip();
+  } else {
+    skip_ = NULL;
+    should_skip_ = false;
+    skip_repeat_ = false;
+  }
+}
+
+void Scanner::Skip(const char* re) {
+  delete skip_;
+  if (re != NULL) {
+    skip_ = new RE(re);
+    should_skip_ = true;
+    skip_repeat_ = false;
+    ConsumeSkip();
+  } else {
+    skip_ = NULL;
+    should_skip_ = false;
+    skip_repeat_ = false;
+  }
+}
+
+void Scanner::DisableSkip() {
+  assert(skip_ != NULL);
+  should_skip_ = false;
+}
+
+void Scanner::EnableSkip() {
+  assert(skip_ != NULL);
+  should_skip_ = true;
+  ConsumeSkip();
+}
+
+int Scanner::LineNumber() const {
+  // TODO: Make it more efficient by keeping track of the last point
+  // where we computed line numbers and counting newlines since then.
+  // We could use std:count, but not all systems have it. :-(
+  int count = 1;
+  for (const char* p = data_.data(); p < input_.data(); ++p)
+    if (*p == '\n')
+      ++count;
+  return count;
+}
+
+int Scanner::Offset() const {
+  return input_.data() - data_.c_str();
+}
+
+bool Scanner::LookingAt(const RE& re) const {
+  int consumed;
+  return re.DoMatch(input_, RE::ANCHOR_START, &consumed, 0, 0);
+}
+
+
+bool Scanner::Consume(const RE& re,
+                      const Arg& arg0,
+                      const Arg& arg1,
+                      const Arg& arg2) {
+  const bool result = re.Consume(&input_, arg0, arg1, arg2);
+  if (result && should_skip_) ConsumeSkip();
+  return result;
+}
+
+// helper function to consume *skip_ and honour save_comments_
+void Scanner::ConsumeSkip() {
+  const char* start_data = input_.data();
+  while (skip_->Consume(&input_)) {
+    if (!skip_repeat_) {
+      // Only one skip allowed.
+      break;
+    }
+  }
+  if (save_comments_) {
+    if (comments_ == NULL) {
+      comments_ = new vector<StringPiece>;
+    }
+    // already pointing one past end, so no need to +1
+    int length = input_.data() - start_data;
+    if (length > 0) {
+      comments_->push_back(StringPiece(start_data, length));
+    }
+  }
+}
+
+
+void Scanner::GetComments(int start, int end, vector<StringPiece> *ranges) {
+  // short circuit out if we've not yet initialized comments_
+  // (e.g., when save_comments is false)
+  if (!comments_) {
+    return;
+  }
+  // TODO: if we guarantee that comments_ will contain StringPieces
+  // that are ordered by their start, then we can do a binary search
+  // for the first StringPiece at or past start and then scan for the
+  // ones contained in the range, quit early (use equal_range or
+  // lower_bound)
+  for (vector<StringPiece>::const_iterator it = comments_->begin();
+       it != comments_->end(); ++it) {
+    if ((it->data() >= data_.c_str() + start &&
+         it->data() + it->size() <= data_.c_str() + end)) {
+      ranges->push_back(*it);
+    }
+  }
+}
+
+
+void Scanner::GetNextComments(vector<StringPiece> *ranges) {
+  // short circuit out if we've not yet initialized comments_
+  // (e.g., when save_comments is false)
+  if (!comments_) {
+    return;
+  }
+  for (vector<StringPiece>::const_iterator it =
+         comments_->begin() + comments_offset_;
+       it != comments_->end(); ++it) {
+    ranges->push_back(*it);
+    ++comments_offset_;
+  }
+}
+
+}   // namespace pcrecpp

Added: httpd/httpd/vendor/pcre/current/pcre_scanner.h
URL: http://svn.apache.org/viewvc/httpd/httpd/vendor/pcre/current/pcre_scanner.h?rev=598339&view=auto
==============================================================================
--- httpd/httpd/vendor/pcre/current/pcre_scanner.h (added)
+++ httpd/httpd/vendor/pcre/current/pcre_scanner.h Mon Nov 26 08:49:53 2007
@@ -0,0 +1,172 @@
+// Copyright (c) 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Sanjay Ghemawat
+//
+// Regular-expression based scanner for parsing an input stream.
+//
+// Example 1: parse a sequence of "var = number" entries from input:
+//
+//      Scanner scanner(input);
+//      string var;
+//      int number;
+//      scanner.SetSkipExpression("\\s+"); // Skip any white space we encounter
+//      while (scanner.Consume("(\\w+) = (\\d+)", &var, &number)) {
+//        ...;
+//      }
+
+#ifndef _PCRE_SCANNER_H
+#define _PCRE_SCANNER_H
+
+#include <assert.h>
+#include <string>
+#include <vector>
+
+#include <pcrecpp.h>
+#include <pcre_stringpiece.h>
+
+namespace pcrecpp {
+
+class PCRECPP_EXP_DEFN Scanner {
+ public:
+  Scanner();
+  explicit Scanner(const std::string& input);
+  ~Scanner();
+
+  // Return current line number.  The returned line-number is
+  // one-based.  I.e. it returns 1 + the number of consumed newlines.
+  //
+  // Note: this method may be slow.  It may take time proportional to
+  // the size of the input.
+  int LineNumber() const;
+
+  // Return the byte-offset that the scanner is looking in the
+  // input data;
+  int Offset() const;
+
+  // Return true iff the start of the remaining input matches "re"
+  bool LookingAt(const RE& re) const;
+
+  // Return true iff all of the following are true
+  //    a. the start of the remaining input matches "re",
+  //    b. if any arguments are supplied, matched sub-patterns can be
+  //       parsed and stored into the arguments.
+  // If it returns true, it skips over the matched input and any
+  // following input that matches the "skip" regular expression.
+  bool Consume(const RE& re,
+               const Arg& arg0 = no_arg,
+               const Arg& arg1 = no_arg,
+               const Arg& arg2 = no_arg
+               // TODO: Allow more arguments?
+               );
+
+  // Set the "skip" regular expression.  If after consuming some data,
+  // a prefix of the input matches this RE, it is automatically
+  // skipped.  For example, a programming language scanner would use
+  // a skip RE that matches white space and comments.
+  //
+  //    scanner.SetSkipExpression("\\s+|//.*|/[*](.|\n)*?[*]/");
+  //
+  // Skipping repeats as long as it succeeds.  We used to let people do
+  // this by writing "(...)*" in the regular expression, but that added
+  // up to lots of recursive calls within the pcre library, so now we
+  // control repetition explicitly via the function call API.
+  //
+  // You can pass NULL for "re" if you do not want any data to be skipped.
+  void Skip(const char* re);   // DEPRECATED; does *not* repeat
+  void SetSkipExpression(const char* re);
+
+  // Temporarily pause "skip"ing. This
+  //   Skip("Foo"); code ; DisableSkip(); code; EnableSkip()
+  // is similar to
+  //   Skip("Foo"); code ; Skip(NULL); code ; Skip("Foo");
+  // but avoids creating/deleting new RE objects.
+  void DisableSkip();
+
+  // Reenable previously paused skipping.  Any prefix of the input
+  // that matches the skip pattern is immediately dropped.
+  void EnableSkip();
+
+  /***** Special wrappers around SetSkip() for some common idioms *****/
+
+  // Arranges to skip whitespace, C comments, C++ comments.
+  // The overall RE is a disjunction of the following REs:
+  //    \\s                     whitespace
+  //    //.*\n                  C++ comment
+  //    /[*](.|\n)*?[*]/        C comment (x*? means minimal repetitions of x)
+  // We get repetition via the semantics of SetSkipExpression, not by using *
+  void SkipCXXComments() {
+    SetSkipExpression("\\s|//.*\n|/[*](?:\n|.)*?[*]/");
+  }
+
+  void set_save_comments(bool comments) {
+    save_comments_ = comments;
+  }
+
+  bool save_comments() {
+    return save_comments_;
+  }
+
+  // Append to vector ranges the comments found in the
+  // byte range [start,end] (inclusive) of the input data.
+  // Only comments that were extracted entirely within that
+  // range are returned: no range splitting of atomically-extracted
+  // comments is performed.
+  void GetComments(int start, int end, std::vector<StringPiece> *ranges);
+
+  // Append to vector ranges the comments added
+  // since the last time this was called. This
+  // functionality is provided for efficiency when
+  // interleaving scanning with parsing.
+  void GetNextComments(std::vector<StringPiece> *ranges);
+
+ private:
+  std::string   data_;          // All the input data
+  StringPiece   input_;         // Unprocessed input
+  RE*           skip_;          // If non-NULL, RE for skipping input
+  bool          should_skip_;   // If true, use skip_
+  bool          skip_repeat_;   // If true, repeat skip_ as long as it works
+  bool          save_comments_; // If true, aggregate the skip expression
+
+  // the skipped comments
+  // TODO: later consider requiring that the StringPieces be added
+  // in order by their start position
+  std::vector<StringPiece> *comments_;
+
+  // the offset into comments_ that has been returned by GetNextComments
+  int           comments_offset_;
+
+  // helper function to consume *skip_ and honour
+  // save_comments_
+  void ConsumeSkip();
+};
+
+}   // namespace pcrecpp
+
+#endif /* _PCRE_SCANNER_H */

Added: httpd/httpd/vendor/pcre/current/pcre_scanner_unittest.cc
URL: http://svn.apache.org/viewvc/httpd/httpd/vendor/pcre/current/pcre_scanner_unittest.cc?rev=598339&view=auto
==============================================================================
--- httpd/httpd/vendor/pcre/current/pcre_scanner_unittest.cc (added)
+++ httpd/httpd/vendor/pcre/current/pcre_scanner_unittest.cc Mon Nov 26 08:49:53 2007
@@ -0,0 +1,158 @@
+// Copyright (c) 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Greg J. Badros
+//
+// Unittest for scanner, especially GetNextComments and GetComments()
+// functionality.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string>
+#include <vector>
+
+#include "pcrecpp.h"
+#include "pcre_stringpiece.h"
+#include "pcre_scanner.h"
+
+#define FLAGS_unittest_stack_size   49152
+
+// Dies with a fatal error if the two values are not equal.
+#define CHECK_EQ(a, b)  do {                                    \
+  if ( (a) != (b) ) {                                           \
+    fprintf(stderr, "%s:%d: Check failed because %s != %s\n",   \
+            __FILE__, __LINE__, #a, #b);                        \
+    exit(1);                                                    \
+  }                                                             \
+} while (0)
+
+using std::vector;
+using pcrecpp::StringPiece;
+using pcrecpp::Scanner;
+
+static void TestScanner() {
+  const char input[] = "\n"
+                       "alpha = 1; // this sets alpha\n"
+                       "bravo = 2; // bravo is set here\n"
+                       "gamma = 33; /* and here is gamma */\n";
+
+  const char *re = "(\\w+) = (\\d+);";
+
+  Scanner s(input);
+  string var;
+  int number;
+  s.SkipCXXComments();
+  s.set_save_comments(true);
+  vector<StringPiece> comments;
+
+  s.Consume(re, &var, &number);
+  CHECK_EQ(var, "alpha");
+  CHECK_EQ(number, 1);
+  CHECK_EQ(s.LineNumber(), 3);
+  s.GetNextComments(&comments);
+  CHECK_EQ(comments.size(), 1);
+  CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
+  comments.resize(0);
+
+  s.Consume(re, &var, &number);
+  CHECK_EQ(var, "bravo");
+  CHECK_EQ(number, 2);
+  s.GetNextComments(&comments);
+  CHECK_EQ(comments.size(), 1);
+  CHECK_EQ(comments[0].as_string(), " // bravo is set here\n");
+  comments.resize(0);
+
+  s.Consume(re, &var, &number);
+  CHECK_EQ(var, "gamma");
+  CHECK_EQ(number, 33);
+  s.GetNextComments(&comments);
+  CHECK_EQ(comments.size(), 1);
+  CHECK_EQ(comments[0].as_string(), " /* and here is gamma */\n");
+  comments.resize(0);
+
+  s.GetComments(0, sizeof(input), &comments);
+  CHECK_EQ(comments.size(), 3);
+  CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
+  CHECK_EQ(comments[1].as_string(), " // bravo is set here\n");
+  CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n");
+  comments.resize(0);
+
+  s.GetComments(0, strchr(input, '/') - input, &comments);
+  CHECK_EQ(comments.size(), 0);
+  comments.resize(0);
+
+  s.GetComments(strchr(input, '/') - input - 1, sizeof(input),
+                &comments);
+  CHECK_EQ(comments.size(), 3);
+  CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
+  CHECK_EQ(comments[1].as_string(), " // bravo is set here\n");
+  CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n");
+  comments.resize(0);
+
+  s.GetComments(strchr(input, '/') - input - 1,
+                strchr(input + 1, '\n') - input + 1, &comments);
+  CHECK_EQ(comments.size(), 1);
+  CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
+  comments.resize(0);
+}
+
+static void TestBigComment() {
+  string input;
+  for (int i = 0; i < 1024; ++i) {
+    char buf[1024];  // definitely big enough
+    sprintf(buf, "    # Comment %d\n", i);
+    input += buf;
+  }
+  input += "name = value;\n";
+
+  Scanner s(input.c_str());
+  s.SetSkipExpression("\\s+|#.*\n");
+
+  string name;
+  string value;
+  s.Consume("(\\w+) = (\\w+);", &name, &value);
+  CHECK_EQ(name, "name");
+  CHECK_EQ(value, "value");
+}
+
+// TODO: also test scanner and big-comment in a thread with a
+//       small stack size
+
+int main(int argc, char** argv) {
+  TestScanner();
+  TestBigComment();
+
+  // Done
+  printf("OK\n");
+
+  return 0;
+}

Added: httpd/httpd/vendor/pcre/current/pcre_stringpiece.cc
URL: http://svn.apache.org/viewvc/httpd/httpd/vendor/pcre/current/pcre_stringpiece.cc?rev=598339&view=auto
==============================================================================
--- httpd/httpd/vendor/pcre/current/pcre_stringpiece.cc (added)
+++ httpd/httpd/vendor/pcre/current/pcre_stringpiece.cc Mon Nov 26 08:49:53 2007
@@ -0,0 +1,43 @@
+// Copyright (c) 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wilsonh@google.com (Wilson Hsieh)
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <iostream>
+#include "pcrecpp_internal.h"
+#include "pcre_stringpiece.h"
+
+std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece) {
+  return (o << piece.as_string());
+}

Added: httpd/httpd/vendor/pcre/current/pcre_stringpiece.h.in
URL: http://svn.apache.org/viewvc/httpd/httpd/vendor/pcre/current/pcre_stringpiece.h.in?rev=598339&view=auto
==============================================================================
--- httpd/httpd/vendor/pcre/current/pcre_stringpiece.h.in (added)
+++ httpd/httpd/vendor/pcre/current/pcre_stringpiece.h.in Mon Nov 26 08:49:53 2007
@@ -0,0 +1,177 @@
+// Copyright (c) 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Sanjay Ghemawat
+//
+// A string like object that points into another piece of memory.
+// Useful for providing an interface that allows clients to easily
+// pass in either a "const char*" or a "string".
+//
+// Arghh!  I wish C++ literals were automatically of type "string".
+
+#ifndef _PCRE_STRINGPIECE_H
+#define _PCRE_STRINGPIECE_H
+
+#include <string.h>
+#include <string>
+#include <iosfwd>    // for ostream forward-declaration
+
+#if @pcre_have_type_traits@
+#define HAVE_TYPE_TRAITS
+#include <type_traits.h>
+#elif @pcre_have_bits_type_traits@
+#define HAVE_TYPE_TRAITS
+#include <bits/type_traits.h>
+#endif
+
+#include <pcre.h>
+
+using std::string;
+
+namespace pcrecpp {
+
+class PCRECPP_EXP_DEFN StringPiece {
+ private:
+  const char*   ptr_;
+  int           length_;
+
+ public:
+  // We provide non-explicit singleton constructors so users can pass
+  // in a "const char*" or a "string" wherever a "StringPiece" is
+  // expected.
+  StringPiece()
+    : ptr_(NULL), length_(0) { }
+  StringPiece(const char* str)
+    : ptr_(str), length_(static_cast<int>(strlen(ptr_))) { }
+  StringPiece(const unsigned char* str)
+    : ptr_(reinterpret_cast<const char*>(str)),
+      length_(static_cast<int>(strlen(ptr_))) { }
+  StringPiece(const string& str)
+    : ptr_(str.data()), length_(static_cast<int>(str.size())) { }
+  StringPiece(const char* offset, int len)
+    : ptr_(offset), length_(len) { }
+
+  // data() may return a pointer to a buffer with embedded NULs, and the
+  // returned buffer may or may not be null terminated.  Therefore it is
+  // typically a mistake to pass data() to a routine that expects a NUL
+  // terminated string.  Use "as_string().c_str()" if you really need to do
+  // this.  Or better yet, change your routine so it does not rely on NUL
+  // termination.
+  const char* data() const { return ptr_; }
+  int size() const { return length_; }
+  bool empty() const { return length_ == 0; }
+
+  void clear() { ptr_ = NULL; length_ = 0; }
+  void set(const char* buffer, int len) { ptr_ = buffer; length_ = len; }
+  void set(const char* str) {
+    ptr_ = str;
+    length_ = static_cast<int>(strlen(str));
+  }
+  void set(const void* buffer, int len) {
+    ptr_ = reinterpret_cast<const char*>(buffer);
+    length_ = len;
+  }
+
+  char operator[](int i) const { return ptr_[i]; }
+
+  void remove_prefix(int n) {
+    ptr_ += n;
+    length_ -= n;
+  }
+
+  void remove_suffix(int n) {
+    length_ -= n;
+  }
+
+  bool operator==(const StringPiece& x) const {
+    return ((length_ == x.length_) &&
+            (memcmp(ptr_, x.ptr_, length_) == 0));
+  }
+  bool operator!=(const StringPiece& x) const {
+    return !(*this == x);
+  }
+
+#define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp)                             \
+  bool operator cmp (const StringPiece& x) const {                           \
+    int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); \
+    return ((r auxcmp 0) || ((r == 0) && (length_ cmp x.length_)));          \
+  }
+  STRINGPIECE_BINARY_PREDICATE(<,  <);
+  STRINGPIECE_BINARY_PREDICATE(<=, <);
+  STRINGPIECE_BINARY_PREDICATE(>=, >);
+  STRINGPIECE_BINARY_PREDICATE(>,  >);
+#undef STRINGPIECE_BINARY_PREDICATE
+
+  int compare(const StringPiece& x) const {
+    int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_);
+    if (r == 0) {
+      if (length_ < x.length_) r = -1;
+      else if (length_ > x.length_) r = +1;
+    }
+    return r;
+  }
+
+  string as_string() const {
+    return string(data(), size());
+  }
+
+  void CopyToString(string* target) const {
+    target->assign(ptr_, length_);
+  }
+
+  // Does "this" start with "x"
+  bool starts_with(const StringPiece& x) const {
+    return ((length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0));
+  }
+};
+
+}   // namespace pcrecpp
+
+// ------------------------------------------------------------------
+// Functions used to create STL containers that use StringPiece
+//  Remember that a StringPiece's lifetime had better be less than
+//  that of the underlying string or char*.  If it is not, then you
+//  cannot safely store a StringPiece into an STL container
+// ------------------------------------------------------------------
+
+#ifdef HAVE_TYPE_TRAITS
+// This makes vector<StringPiece> really fast for some STL implementations
+template<> struct __type_traits<pcrecpp::StringPiece> {
+  typedef __true_type    has_trivial_default_constructor;
+  typedef __true_type    has_trivial_copy_constructor;
+  typedef __true_type    has_trivial_assignment_operator;
+  typedef __true_type    has_trivial_destructor;
+  typedef __true_type    is_POD_type;
+};
+#endif
+
+// allow StringPiece to be logged
+std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece);
+
+#endif /* _PCRE_STRINGPIECE_H */

Added: httpd/httpd/vendor/pcre/current/pcre_stringpiece_unittest.cc
URL: http://svn.apache.org/viewvc/httpd/httpd/vendor/pcre/current/pcre_stringpiece_unittest.cc?rev=598339&view=auto
==============================================================================
--- httpd/httpd/vendor/pcre/current/pcre_stringpiece_unittest.cc (added)
+++ httpd/httpd/vendor/pcre/current/pcre_stringpiece_unittest.cc Mon Nov 26 08:49:53 2007
@@ -0,0 +1,151 @@
+// Copyright 2003 and onwards Google Inc.
+// Author: Sanjay Ghemawat
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <map>
+#include <algorithm>    // for make_pair
+
+#include "pcrecpp.h"
+#include "pcre_stringpiece.h"
+
+// CHECK dies with a fatal error if condition is not true.  It is *not*
+// controlled by NDEBUG, so the check will be executed regardless of
+// compilation mode.  Therefore, it is safe to do things like:
+//    CHECK(fp->Write(x) == 4)
+#define CHECK(condition) do {                           \
+  if (!(condition)) {                                   \
+    fprintf(stderr, "%s:%d: Check failed: %s\n",        \
+            __FILE__, __LINE__, #condition);            \
+    exit(1);                                            \
+  }                                                     \
+} while (0)
+
+using std::map;
+using std::make_pair;
+using pcrecpp::StringPiece;
+
+static void CheckSTLComparator() {
+  string s1("foo");
+  string s2("bar");
+  string s3("baz");
+
+  StringPiece p1(s1);
+  StringPiece p2(s2);
+  StringPiece p3(s3);
+
+  typedef map<StringPiece, int> TestMap;
+  TestMap map;
+
+  map.insert(make_pair(p1, 0));
+  map.insert(make_pair(p2, 1));
+  map.insert(make_pair(p3, 2));
+  CHECK(map.size() == 3);
+
+  TestMap::const_iterator iter = map.begin();
+  CHECK(iter->second == 1);
+  ++iter;
+  CHECK(iter->second == 2);
+  ++iter;
+  CHECK(iter->second == 0);
+  ++iter;
+  CHECK(iter == map.end());
+
+  TestMap::iterator new_iter = map.find("zot");
+  CHECK(new_iter == map.end());
+
+  new_iter = map.find("bar");
+  CHECK(new_iter != map.end());
+
+  map.erase(new_iter);
+  CHECK(map.size() == 2);
+
+  iter = map.begin();
+  CHECK(iter->second == 2);
+  ++iter;
+  CHECK(iter->second == 0);
+  ++iter;
+  CHECK(iter == map.end());
+}
+
+static void CheckComparisonOperators() {
+#define CMP_Y(op, x, y)                                         \
+  CHECK( (StringPiece((x)) op StringPiece((y))));               \
+  CHECK( (StringPiece((x)).compare(StringPiece((y))) op 0))
+
+#define CMP_N(op, x, y)                                         \
+  CHECK(!(StringPiece((x)) op StringPiece((y))));               \
+  CHECK(!(StringPiece((x)).compare(StringPiece((y))) op 0))
+
+  CMP_Y(==, "",   "");
+  CMP_Y(==, "a",  "a");
+  CMP_Y(==, "aa", "aa");
+  CMP_N(==, "a",  "");
+  CMP_N(==, "",   "a");
+  CMP_N(==, "a",  "b");
+  CMP_N(==, "a",  "aa");
+  CMP_N(==, "aa", "a");
+
+  CMP_N(!=, "",   "");
+  CMP_N(!=, "a",  "a");
+  CMP_N(!=, "aa", "aa");
+  CMP_Y(!=, "a",  "");
+  CMP_Y(!=, "",   "a");
+  CMP_Y(!=, "a",  "b");
+  CMP_Y(!=, "a",  "aa");
+  CMP_Y(!=, "aa", "a");
+
+  CMP_Y(<, "a",  "b");
+  CMP_Y(<, "a",  "aa");
+  CMP_Y(<, "aa", "b");
+  CMP_Y(<, "aa", "bb");
+  CMP_N(<, "a",  "a");
+  CMP_N(<, "b",  "a");
+  CMP_N(<, "aa", "a");
+  CMP_N(<, "b",  "aa");
+  CMP_N(<, "bb", "aa");
+
+  CMP_Y(<=, "a",  "a");
+  CMP_Y(<=, "a",  "b");
+  CMP_Y(<=, "a",  "aa");
+  CMP_Y(<=, "aa", "b");
+  CMP_Y(<=, "aa", "bb");
+  CMP_N(<=, "b",  "a");
+  CMP_N(<=, "aa", "a");
+  CMP_N(<=, "b",  "aa");
+  CMP_N(<=, "bb", "aa");
+
+  CMP_N(>=, "a",  "b");
+  CMP_N(>=, "a",  "aa");
+  CMP_N(>=, "aa", "b");
+  CMP_N(>=, "aa", "bb");
+  CMP_Y(>=, "a",  "a");
+  CMP_Y(>=, "b",  "a");
+  CMP_Y(>=, "aa", "a");
+  CMP_Y(>=, "b",  "aa");
+  CMP_Y(>=, "bb", "aa");
+
+  CMP_N(>, "a",  "a");
+  CMP_N(>, "a",  "b");
+  CMP_N(>, "a",  "aa");
+  CMP_N(>, "aa", "b");
+  CMP_N(>, "aa", "bb");
+  CMP_Y(>, "b",  "a");
+  CMP_Y(>, "aa", "a");
+  CMP_Y(>, "b",  "aa");
+  CMP_Y(>, "bb", "aa");
+
+#undef CMP_Y
+#undef CMP_N
+}
+
+int main(int argc, char** argv) {
+  CheckComparisonOperators();
+  CheckSTLComparator();
+
+  printf("OK\n");
+  return 0;
+}

Added: httpd/httpd/vendor/pcre/current/pcre_study.c
URL: http://svn.apache.org/viewvc/httpd/httpd/vendor/pcre/current/pcre_study.c?rev=598339&view=auto
==============================================================================
--- httpd/httpd/vendor/pcre/current/pcre_study.c (added)
+++ httpd/httpd/vendor/pcre/current/pcre_study.c Mon Nov 26 08:49:53 2007
@@ -0,0 +1,579 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2007 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_study(), along with local
+supporting functions. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/* Returns from set_start_bits() */
+
+enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE };
+
+
+/*************************************************
+*      Set a bit and maybe its alternate case    *
+*************************************************/
+
+/* Given a character, set its bit in the table, and also the bit for the other
+version of a letter if we are caseless.
+
+Arguments:
+  start_bits    points to the bit map
+  c             is the character
+  caseless      the caseless flag
+  cd            the block with char table pointers
+
+Returns:        nothing
+*/
+
+static void
+set_bit(uschar *start_bits, unsigned int c, BOOL caseless, compile_data *cd)
+{
+start_bits[c/8] |= (1 << (c&7));
+if (caseless && (cd->ctypes[c] & ctype_letter) != 0)
+  start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7));
+}
+
+
+
+/*************************************************
+*          Create bitmap of starting bytes       *
+*************************************************/
+
+/* This function scans a compiled unanchored expression recursively and
+attempts to build a bitmap of the set of possible starting bytes. As time goes
+by, we may be able to get more clever at doing this. The SSB_CONTINUE return is
+useful for parenthesized groups in patterns such as (a*)b where the group
+provides some optional starting bytes but scanning must continue at the outer
+level to find at least one mandatory byte. At the outermost level, this
+function fails unless the result is SSB_DONE.
+
+Arguments:
+  code         points to an expression
+  start_bits   points to a 32-byte table, initialized to 0
+  caseless     the current state of the caseless flag
+  utf8         TRUE if in UTF-8 mode
+  cd           the block with char table pointers
+
+Returns:       SSB_FAIL     => Failed to find any starting bytes
+               SSB_DONE     => Found mandatory starting bytes
+               SSB_CONTINUE => Found optional starting bytes
+*/
+
+static int
+set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless,
+  BOOL utf8, compile_data *cd)
+{
+register int c;
+int yield = SSB_DONE;
+
+#if 0
+/* ========================================================================= */
+/* The following comment and code was inserted in January 1999. In May 2006,
+when it was observed to cause compiler warnings about unused values, I took it
+out again. If anybody is still using OS/2, they will have to put it back
+manually. */
+
+/* This next statement and the later reference to dummy are here in order to
+trick the optimizer of the IBM C compiler for OS/2 into generating correct
+code. Apparently IBM isn't going to fix the problem, and we would rather not
+disable optimization (in this module it actually makes a big difference, and
+the pcre module can use all the optimization it can get). */
+
+volatile int dummy;
+/* ========================================================================= */
+#endif
+
+do
+  {
+  const uschar *tcode = code + (((int)*code == OP_CBRA)? 3:1) + LINK_SIZE;
+  BOOL try_next = TRUE;
+
+  while (try_next)    /* Loop for items in this branch */
+    {
+    int rc;
+    switch(*tcode)
+      {
+      /* Fail if we reach something we don't understand */
+
+      default:
+      return SSB_FAIL;
+
+      /* If we hit a bracket or a positive lookahead assertion, recurse to set
+      bits from within the subpattern. If it can't find anything, we have to
+      give up. If it finds some mandatory character(s), we are done for this
+      branch. Otherwise, carry on scanning after the subpattern. */
+
+      case OP_BRA:
+      case OP_SBRA:
+      case OP_CBRA:
+      case OP_SCBRA:
+      case OP_ONCE:
+      case OP_ASSERT:
+      rc = set_start_bits(tcode, start_bits, caseless, utf8, cd);
+      if (rc == SSB_FAIL) return SSB_FAIL;
+      if (rc == SSB_DONE) try_next = FALSE; else
+        {
+        do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
+        tcode += 1 + LINK_SIZE;
+        }
+      break;
+
+      /* If we hit ALT or KET, it means we haven't found anything mandatory in
+      this branch, though we might have found something optional. For ALT, we
+      continue with the next alternative, but we have to arrange that the final
+      result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET,
+      return SSB_CONTINUE: if this is the top level, that indicates failure,
+      but after a nested subpattern, it causes scanning to continue. */
+
+      case OP_ALT:
+      yield = SSB_CONTINUE;
+      try_next = FALSE;
+      break;
+
+      case OP_KET:
+      case OP_KETRMAX:
+      case OP_KETRMIN:
+      return SSB_CONTINUE;
+
+      /* Skip over callout */
+
+      case OP_CALLOUT:
+      tcode += 2 + 2*LINK_SIZE;
+      break;
+
+      /* Skip over lookbehind and negative lookahead assertions */
+
+      case OP_ASSERT_NOT:
+      case OP_ASSERTBACK:
+      case OP_ASSERTBACK_NOT:
+      do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
+      tcode += 1 + LINK_SIZE;
+      break;
+
+      /* Skip over an option setting, changing the caseless flag */
+
+      case OP_OPT:
+      caseless = (tcode[1] & PCRE_CASELESS) != 0;
+      tcode += 2;
+      break;
+
+      /* BRAZERO does the bracket, but carries on. */
+
+      case OP_BRAZERO:
+      case OP_BRAMINZERO:
+      if (set_start_bits(++tcode, start_bits, caseless, utf8, cd) == SSB_FAIL)
+        return SSB_FAIL;
+/* =========================================================================
+      See the comment at the head of this function concerning the next line,
+      which was an old fudge for the benefit of OS/2.
+      dummy = 1;
+  ========================================================================= */
+      do tcode += GET(tcode,1); while (*tcode == OP_ALT);
+      tcode += 1 + LINK_SIZE;
+      break;
+
+      /* Single-char * or ? sets the bit and tries the next item */
+
+      case OP_STAR:
+      case OP_MINSTAR:
+      case OP_POSSTAR:
+      case OP_QUERY:
+      case OP_MINQUERY:
+      case OP_POSQUERY:
+      set_bit(start_bits, tcode[1], caseless, cd);
+      tcode += 2;
+#ifdef SUPPORT_UTF8
+      if (utf8 && tcode[-1] >= 0xc0)
+        tcode += _pcre_utf8_table4[tcode[-1] & 0x3f];
+#endif
+      break;
+
+      /* Single-char upto sets the bit and tries the next */
+
+      case OP_UPTO:
+      case OP_MINUPTO:
+      case OP_POSUPTO:
+      set_bit(start_bits, tcode[3], caseless, cd);
+      tcode += 4;
+#ifdef SUPPORT_UTF8
+      if (utf8 && tcode[-1] >= 0xc0)
+        tcode += _pcre_utf8_table4[tcode[-1] & 0x3f];
+#endif
+      break;
+
+      /* At least one single char sets the bit and stops */
+
+      case OP_EXACT:       /* Fall through */
+      tcode += 2;
+
+      case OP_CHAR:
+      case OP_CHARNC:
+      case OP_PLUS:
+      case OP_MINPLUS:
+      case OP_POSPLUS:
+      set_bit(start_bits, tcode[1], caseless, cd);
+      try_next = FALSE;
+      break;
+
+      /* Single character type sets the bits and stops */
+
+      case OP_NOT_DIGIT:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= ~cd->cbits[c+cbit_digit];
+      try_next = FALSE;
+      break;
+
+      case OP_DIGIT:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= cd->cbits[c+cbit_digit];
+      try_next = FALSE;
+      break;
+
+      /* The cbit_space table has vertical tab as whitespace; we have to
+      discard it. */
+
+      case OP_NOT_WHITESPACE:
+      for (c = 0; c < 32; c++)
+        {
+        int d = cd->cbits[c+cbit_space];
+        if (c == 1) d &= ~0x08;
+        start_bits[c] |= ~d;
+        }
+      try_next = FALSE;
+      break;
+
+      /* The cbit_space table has vertical tab as whitespace; we have to
+      discard it. */
+
+      case OP_WHITESPACE:
+      for (c = 0; c < 32; c++)
+        {
+        int d = cd->cbits[c+cbit_space];
+        if (c == 1) d &= ~0x08;
+        start_bits[c] |= d;
+        }
+      try_next = FALSE;
+      break;
+
+      case OP_NOT_WORDCHAR:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= ~cd->cbits[c+cbit_word];
+      try_next = FALSE;
+      break;
+
+      case OP_WORDCHAR:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= cd->cbits[c+cbit_word];
+      try_next = FALSE;
+      break;
+
+      /* One or more character type fudges the pointer and restarts, knowing
+      it will hit a single character type and stop there. */
+
+      case OP_TYPEPLUS:
+      case OP_TYPEMINPLUS:
+      tcode++;
+      break;
+
+      case OP_TYPEEXACT:
+      tcode += 3;
+      break;
+
+      /* Zero or more repeats of character types set the bits and then
+      try again. */
+
+      case OP_TYPEUPTO:
+      case OP_TYPEMINUPTO:
+      case OP_TYPEPOSUPTO:
+      tcode += 2;               /* Fall through */
+
+      case OP_TYPESTAR:
+      case OP_TYPEMINSTAR:
+      case OP_TYPEPOSSTAR:
+      case OP_TYPEQUERY:
+      case OP_TYPEMINQUERY:
+      case OP_TYPEPOSQUERY:
+      switch(tcode[1])
+        {
+        case OP_ANY:
+        return SSB_FAIL;
+
+        case OP_NOT_DIGIT:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= ~cd->cbits[c+cbit_digit];
+        break;
+
+        case OP_DIGIT:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= cd->cbits[c+cbit_digit];
+        break;
+
+        /* The cbit_space table has vertical tab as whitespace; we have to
+        discard it. */
+
+        case OP_NOT_WHITESPACE:
+        for (c = 0; c < 32; c++)
+          {
+          int d = cd->cbits[c+cbit_space];
+          if (c == 1) d &= ~0x08;
+          start_bits[c] |= ~d;
+          }
+        break;
+
+        /* The cbit_space table has vertical tab as whitespace; we have to
+        discard it. */
+
+        case OP_WHITESPACE:
+        for (c = 0; c < 32; c++)
+          {
+          int d = cd->cbits[c+cbit_space];
+          if (c == 1) d &= ~0x08;
+          start_bits[c] |= d;
+          }
+        break;
+
+        case OP_NOT_WORDCHAR:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= ~cd->cbits[c+cbit_word];
+        break;
+
+        case OP_WORDCHAR:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= cd->cbits[c+cbit_word];
+        break;
+        }
+
+      tcode += 2;
+      break;
+
+      /* Character class where all the information is in a bit map: set the
+      bits and either carry on or not, according to the repeat count. If it was
+      a negative class, and we are operating with UTF-8 characters, any byte
+      with a value >= 0xc4 is a potentially valid starter because it starts a
+      character with a value > 255. */
+
+      case OP_NCLASS:
+#ifdef SUPPORT_UTF8
+      if (utf8)
+        {
+        start_bits[24] |= 0xf0;              /* Bits for 0xc4 - 0xc8 */
+        memset(start_bits+25, 0xff, 7);      /* Bits for 0xc9 - 0xff */
+        }
+#endif
+      /* Fall through */
+
+      case OP_CLASS:
+        {
+        tcode++;
+
+        /* In UTF-8 mode, the bits in a bit map correspond to character
+        values, not to byte values. However, the bit map we are constructing is
+        for byte values. So we have to do a conversion for characters whose
+        value is > 127. In fact, there are only two possible starting bytes for
+        characters in the range 128 - 255. */
+
+#ifdef SUPPORT_UTF8
+        if (utf8)
+          {
+          for (c = 0; c < 16; c++) start_bits[c] |= tcode[c];
+          for (c = 128; c < 256; c++)
+            {
+            if ((tcode[c/8] && (1 << (c&7))) != 0)
+              {
+              int d = (c >> 6) | 0xc0;            /* Set bit for this starter */
+              start_bits[d/8] |= (1 << (d&7));    /* and then skip on to the */
+              c = (c & 0xc0) + 0x40 - 1;          /* next relevant character. */
+              }
+            }
+          }
+
+        /* In non-UTF-8 mode, the two bit maps are completely compatible. */
+
+        else
+#endif
+          {
+          for (c = 0; c < 32; c++) start_bits[c] |= tcode[c];
+          }
+
+        /* Advance past the bit map, and act on what follows */
+
+        tcode += 32;
+        switch (*tcode)
+          {
+          case OP_CRSTAR:
+          case OP_CRMINSTAR:
+          case OP_CRQUERY:
+          case OP_CRMINQUERY:
+          tcode++;
+          break;
+
+          case OP_CRRANGE:
+          case OP_CRMINRANGE:
+          if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5;
+            else try_next = FALSE;
+          break;
+
+          default:
+          try_next = FALSE;
+          break;
+          }
+        }
+      break; /* End of bitmap class handling */
+
+      }      /* End of switch */
+    }        /* End of try_next loop */
+
+  code += GET(code, 1);   /* Advance to next branch */
+  }
+while (*code == OP_ALT);
+return yield;
+}
+
+
+
+/*************************************************
+*          Study a compiled expression           *
+*************************************************/
+
+/* This function is handed a compiled expression that it must study to produce
+information that will speed up the matching. It returns a pcre_extra block
+which then gets handed back to pcre_exec().
+
+Arguments:
+  re        points to the compiled expression
+  options   contains option bits
+  errorptr  points to where to place error messages;
+            set NULL unless error
+
+Returns:    pointer to a pcre_extra block, with study_data filled in and the
+              appropriate flag set;
+            NULL on error or if no optimization possible
+*/
+
+PCRE_EXP_DEFN pcre_extra *
+pcre_study(const pcre *external_re, int options, const char **errorptr)
+{
+uschar start_bits[32];
+pcre_extra *extra;
+pcre_study_data *study;
+const uschar *tables;
+uschar *code;
+compile_data compile_block;
+const real_pcre *re = (const real_pcre *)external_re;
+
+*errorptr = NULL;
+
+if (re == NULL || re->magic_number != MAGIC_NUMBER)
+  {
+  *errorptr = "argument is not a compiled regular expression";
+  return NULL;
+  }
+
+if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
+  {
+  *errorptr = "unknown or incorrect option bit(s) set";
+  return NULL;
+  }
+
+code = (uschar *)re + re->name_table_offset +
+  (re->name_count * re->name_entry_size);
+
+/* For an anchored pattern, or an unanchored pattern that has a first char, or
+a multiline pattern that matches only at "line starts", no further processing
+at present. */
+
+if ((re->options & PCRE_ANCHORED) != 0 ||
+    (re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) != 0)
+  return NULL;
+
+/* Set the character tables in the block that is passed around */
+
+tables = re->tables;
+if (tables == NULL)
+  (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
+  (void *)(&tables));
+
+compile_block.lcc = tables + lcc_offset;
+compile_block.fcc = tables + fcc_offset;
+compile_block.cbits = tables + cbits_offset;
+compile_block.ctypes = tables + ctypes_offset;
+
+/* See if we can find a fixed set of initial characters for the pattern. */
+
+memset(start_bits, 0, 32 * sizeof(uschar));
+if (set_start_bits(code, start_bits, (re->options & PCRE_CASELESS) != 0,
+  (re->options & PCRE_UTF8) != 0, &compile_block) != SSB_DONE) return NULL;
+
+/* Get a pcre_extra block and a pcre_study_data block. The study data is put in
+the latter, which is pointed to by the former, which may also get additional
+data set later by the calling program. At the moment, the size of
+pcre_study_data is fixed. We nevertheless save it in a field for returning via
+the pcre_fullinfo() function so that if it becomes variable in the future, we
+don't have to change that code. */
+
+extra = (pcre_extra *)(pcre_malloc)
+  (sizeof(pcre_extra) + sizeof(pcre_study_data));
+
+if (extra == NULL)
+  {
+  *errorptr = "failed to get memory";
+  return NULL;
+  }
+
+study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra));
+extra->flags = PCRE_EXTRA_STUDY_DATA;
+extra->study_data = study;
+
+study->size = sizeof(pcre_study_data);
+study->options = PCRE_STUDY_MAPPED;
+memcpy(study->start_bits, start_bits, sizeof(start_bits));
+
+return extra;
+}
+
+/* End of pcre_study.c */

Added: httpd/httpd/vendor/pcre/current/pcre_tables.c
URL: http://svn.apache.org/viewvc/httpd/httpd/vendor/pcre/current/pcre_tables.c?rev=598339&view=auto
==============================================================================
--- httpd/httpd/vendor/pcre/current/pcre_tables.c (added)
+++ httpd/httpd/vendor/pcre/current/pcre_tables.c Mon Nov 26 08:49:53 2007
@@ -0,0 +1,318 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2007 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains some fixed tables that are used by more than one of the
+PCRE code modules. The tables are also #included by the pcretest program, which
+uses macros to change their names from _pcre_xxx to xxxx, thereby avoiding name
+clashes with the library. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
+the definition is next to the definition of the opcodes in pcre_internal.h. */
+
+const uschar _pcre_OP_lengths[] = { OP_LENGTHS };
+
+
+
+/*************************************************
+*           Tables for UTF-8 support             *
+*************************************************/
+
+/* These are the breakpoints for different numbers of bytes in a UTF-8
+character. */
+
+#ifdef SUPPORT_UTF8
+
+const int _pcre_utf8_table1[] =
+  { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
+
+const int _pcre_utf8_table1_size = sizeof(_pcre_utf8_table1)/sizeof(int);
+
+/* These are the indicator bits and the mask for the data bits to set in the
+first byte of a character, indexed by the number of additional bytes. */
+
+const int _pcre_utf8_table2[] = { 0,    0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
+const int _pcre_utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
+
+/* Table of the number of extra bytes, indexed by the first byte masked with
+0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */
+
+const uschar _pcre_utf8_table4[] = {
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
+
+/* The pcre_utt[] table below translates Unicode property names into type and
+code values. It is searched by binary chop, so must be in collating sequence of
+name. Originally, the table contained pointers to the name strings in the first
+field of each entry. However, that leads to a large number of relocations when
+a shared library is dynamically loaded. A significant reduction is made by
+putting all the names into a single, large string and then using offsets in the
+table itself. Maintenance is more error-prone, but frequent changes to this
+data is unlikely. */
+
+const char _pcre_utt_names[] =
+  "Any\0"
+  "Arabic\0"
+  "Armenian\0"
+  "Balinese\0"
+  "Bengali\0"
+  "Bopomofo\0"
+  "Braille\0"
+  "Buginese\0"
+  "Buhid\0"
+  "C\0"
+  "Canadian_Aboriginal\0"
+  "Cc\0"
+  "Cf\0"
+  "Cherokee\0"
+  "Cn\0"
+  "Co\0"
+  "Common\0"
+  "Coptic\0"
+  "Cs\0"
+  "Cuneiform\0"
+  "Cypriot\0"
+  "Cyrillic\0"
+  "Deseret\0"
+  "Devanagari\0"
+  "Ethiopic\0"
+  "Georgian\0"
+  "Glagolitic\0"
+  "Gothic\0"
+  "Greek\0"
+  "Gujarati\0"
+  "Gurmukhi\0"
+  "Han\0"
+  "Hangul\0"
+  "Hanunoo\0"
+  "Hebrew\0"
+  "Hiragana\0"
+  "Inherited\0"
+  "Kannada\0"
+  "Katakana\0"
+  "Kharoshthi\0"
+  "Khmer\0"
+  "L\0"
+  "L&\0"
+  "Lao\0"
+  "Latin\0"
+  "Limbu\0"
+  "Linear_B\0"
+  "Ll\0"
+  "Lm\0"
+  "Lo\0"
+  "Lt\0"
+  "Lu\0"
+  "M\0"
+  "Malayalam\0"
+  "Mc\0"
+  "Me\0"
+  "Mn\0"
+  "Mongolian\0"
+  "Myanmar\0"
+  "N\0"
+  "Nd\0"
+  "New_Tai_Lue\0"
+  "Nko\0"
+  "Nl\0"
+  "No\0"
+  "Ogham\0"
+  "Old_Italic\0"
+  "Old_Persian\0"
+  "Oriya\0"
+  "Osmanya\0"
+  "P\0"
+  "Pc\0"
+  "Pd\0"
+  "Pe\0"
+  "Pf\0"
+  "Phags_Pa\0"
+  "Phoenician\0"
+  "Pi\0"
+  "Po\0"
+  "Ps\0"
+  "Runic\0"
+  "S\0"
+  "Sc\0"
+  "Shavian\0"
+  "Sinhala\0"
+  "Sk\0"
+  "Sm\0"
+  "So\0"
+  "Syloti_Nagri\0"
+  "Syriac\0"
+  "Tagalog\0"
+  "Tagbanwa\0"
+  "Tai_Le\0"
+  "Tamil\0"
+  "Telugu\0"
+  "Thaana\0"
+  "Thai\0"
+  "Tibetan\0"
+  "Tifinagh\0"
+  "Ugaritic\0"
+  "Yi\0"
+  "Z\0"
+  "Zl\0"
+  "Zp\0"
+  "Zs\0";
+
+const ucp_type_table _pcre_utt[] = {
+  { 0,   PT_ANY, 0 },
+  { 4,   PT_SC, ucp_Arabic },
+  { 11,  PT_SC, ucp_Armenian },
+  { 20,  PT_SC, ucp_Balinese },
+  { 29,  PT_SC, ucp_Bengali },
+  { 37,  PT_SC, ucp_Bopomofo },
+  { 46,  PT_SC, ucp_Braille },
+  { 54,  PT_SC, ucp_Buginese },
+  { 63,  PT_SC, ucp_Buhid },
+  { 69,  PT_GC, ucp_C },
+  { 71,  PT_SC, ucp_Canadian_Aboriginal },
+  { 91,  PT_PC, ucp_Cc },
+  { 94,  PT_PC, ucp_Cf },
+  { 97,  PT_SC, ucp_Cherokee },
+  { 106, PT_PC, ucp_Cn },
+  { 109, PT_PC, ucp_Co },
+  { 112, PT_SC, ucp_Common },
+  { 119, PT_SC, ucp_Coptic },
+  { 126, PT_PC, ucp_Cs },
+  { 129, PT_SC, ucp_Cuneiform },
+  { 139, PT_SC, ucp_Cypriot },
+  { 147, PT_SC, ucp_Cyrillic },
+  { 156, PT_SC, ucp_Deseret },
+  { 164, PT_SC, ucp_Devanagari },
+  { 175, PT_SC, ucp_Ethiopic },
+  { 184, PT_SC, ucp_Georgian },
+  { 193, PT_SC, ucp_Glagolitic },
+  { 204, PT_SC, ucp_Gothic },
+  { 211, PT_SC, ucp_Greek },
+  { 217, PT_SC, ucp_Gujarati },
+  { 226, PT_SC, ucp_Gurmukhi },
+  { 235, PT_SC, ucp_Han },
+  { 239, PT_SC, ucp_Hangul },
+  { 246, PT_SC, ucp_Hanunoo },
+  { 254, PT_SC, ucp_Hebrew },
+  { 261, PT_SC, ucp_Hiragana },
+  { 270, PT_SC, ucp_Inherited },
+  { 280, PT_SC, ucp_Kannada },
+  { 288, PT_SC, ucp_Katakana },
+  { 297, PT_SC, ucp_Kharoshthi },
+  { 308, PT_SC, ucp_Khmer },
+  { 314, PT_GC, ucp_L },
+  { 316, PT_LAMP, 0 },
+  { 319, PT_SC, ucp_Lao },
+  { 323, PT_SC, ucp_Latin },
+  { 329, PT_SC, ucp_Limbu },
+  { 335, PT_SC, ucp_Linear_B },
+  { 344, PT_PC, ucp_Ll },
+  { 347, PT_PC, ucp_Lm },
+  { 350, PT_PC, ucp_Lo },
+  { 353, PT_PC, ucp_Lt },
+  { 356, PT_PC, ucp_Lu },
+  { 359, PT_GC, ucp_M },
+  { 361, PT_SC, ucp_Malayalam },
+  { 371, PT_PC, ucp_Mc },
+  { 374, PT_PC, ucp_Me },
+  { 377, PT_PC, ucp_Mn },
+  { 380, PT_SC, ucp_Mongolian },
+  { 390, PT_SC, ucp_Myanmar },
+  { 398, PT_GC, ucp_N },
+  { 400, PT_PC, ucp_Nd },
+  { 403, PT_SC, ucp_New_Tai_Lue },
+  { 415, PT_SC, ucp_Nko },
+  { 419, PT_PC, ucp_Nl },
+  { 422, PT_PC, ucp_No },
+  { 425, PT_SC, ucp_Ogham },
+  { 431, PT_SC, ucp_Old_Italic },
+  { 442, PT_SC, ucp_Old_Persian },
+  { 454, PT_SC, ucp_Oriya },
+  { 460, PT_SC, ucp_Osmanya },
+  { 468, PT_GC, ucp_P },
+  { 470, PT_PC, ucp_Pc },
+  { 473, PT_PC, ucp_Pd },
+  { 476, PT_PC, ucp_Pe },
+  { 479, PT_PC, ucp_Pf },
+  { 482, PT_SC, ucp_Phags_Pa },
+  { 491, PT_SC, ucp_Phoenician },
+  { 502, PT_PC, ucp_Pi },
+  { 505, PT_PC, ucp_Po },
+  { 508, PT_PC, ucp_Ps },
+  { 511, PT_SC, ucp_Runic },
+  { 517, PT_GC, ucp_S },
+  { 519, PT_PC, ucp_Sc },
+  { 522, PT_SC, ucp_Shavian },
+  { 530, PT_SC, ucp_Sinhala },
+  { 538, PT_PC, ucp_Sk },
+  { 541, PT_PC, ucp_Sm },
+  { 544, PT_PC, ucp_So },
+  { 547, PT_SC, ucp_Syloti_Nagri },
+  { 560, PT_SC, ucp_Syriac },
+  { 567, PT_SC, ucp_Tagalog },
+  { 575, PT_SC, ucp_Tagbanwa },
+  { 584, PT_SC, ucp_Tai_Le },
+  { 591, PT_SC, ucp_Tamil },
+  { 597, PT_SC, ucp_Telugu },
+  { 604, PT_SC, ucp_Thaana },
+  { 611, PT_SC, ucp_Thai },
+  { 616, PT_SC, ucp_Tibetan },
+  { 624, PT_SC, ucp_Tifinagh },
+  { 633, PT_SC, ucp_Ugaritic },
+  { 642, PT_SC, ucp_Yi },
+  { 645, PT_GC, ucp_Z },
+  { 647, PT_PC, ucp_Zl },
+  { 650, PT_PC, ucp_Zp },
+  { 653, PT_PC, ucp_Zs }
+};
+
+const int _pcre_utt_size = sizeof(_pcre_utt)/sizeof(ucp_type_table);
+
+#endif  /* SUPPORT_UTF8 */
+
+/* End of pcre_tables.c */

Added: httpd/httpd/vendor/pcre/current/pcre_try_flipped.c
URL: http://svn.apache.org/viewvc/httpd/httpd/vendor/pcre/current/pcre_try_flipped.c?rev=598339&view=auto
==============================================================================
--- httpd/httpd/vendor/pcre/current/pcre_try_flipped.c (added)
+++ httpd/httpd/vendor/pcre/current/pcre_try_flipped.c Mon Nov 26 08:49:53 2007
@@ -0,0 +1,137 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2007 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function that tests a compiled pattern to
+see if it was compiled with the opposite endianness. If so, it uses an
+auxiliary local function to flip the appropriate bytes. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+*         Flip bytes in an integer               *
+*************************************************/
+
+/* This function is called when the magic number in a regex doesn't match, in
+order to flip its bytes to see if we are dealing with a pattern that was
+compiled on a host of different endianness. If so, this function is used to
+flip other byte values.
+
+Arguments:
+  value        the number to flip
+  n            the number of bytes to flip (assumed to be 2 or 4)
+
+Returns:       the flipped value
+*/
+
+static unsigned long int
+byteflip(unsigned long int value, int n)
+{
+if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
+return ((value & 0x000000ff) << 24) |
+       ((value & 0x0000ff00) <<  8) |
+       ((value & 0x00ff0000) >>  8) |
+       ((value & 0xff000000) >> 24);
+}
+
+
+
+/*************************************************
+*       Test for a byte-flipped compiled regex   *
+*************************************************/
+
+/* This function is called from pcre_exec(), pcre_dfa_exec(), and also from
+pcre_fullinfo(). Its job is to test whether the regex is byte-flipped - that
+is, it was compiled on a system of opposite endianness. The function is called
+only when the native MAGIC_NUMBER test fails. If the regex is indeed flipped,
+we flip all the relevant values into a different data block, and return it.
+
+Arguments:
+  re               points to the regex
+  study            points to study data, or NULL
+  internal_re      points to a new regex block
+  internal_study   points to a new study block
+
+Returns:           the new block if is is indeed a byte-flipped regex
+                   NULL if it is not
+*/
+
+real_pcre *
+_pcre_try_flipped(const real_pcre *re, real_pcre *internal_re,
+  const pcre_study_data *study, pcre_study_data *internal_study)
+{
+if (byteflip(re->magic_number, sizeof(re->magic_number)) != MAGIC_NUMBER)
+  return NULL;
+
+*internal_re = *re;           /* To copy other fields */
+internal_re->size = byteflip(re->size, sizeof(re->size));
+internal_re->options = byteflip(re->options, sizeof(re->options));
+internal_re->flags = (pcre_uint16)byteflip(re->flags, sizeof(re->flags));
+internal_re->top_bracket =
+  (pcre_uint16)byteflip(re->top_bracket, sizeof(re->top_bracket));
+internal_re->top_backref =
+  (pcre_uint16)byteflip(re->top_backref, sizeof(re->top_backref));
+internal_re->first_byte =
+  (pcre_uint16)byteflip(re->first_byte, sizeof(re->first_byte));
+internal_re->req_byte =
+  (pcre_uint16)byteflip(re->req_byte, sizeof(re->req_byte));
+internal_re->name_table_offset =
+  (pcre_uint16)byteflip(re->name_table_offset, sizeof(re->name_table_offset));
+internal_re->name_entry_size =
+  (pcre_uint16)byteflip(re->name_entry_size, sizeof(re->name_entry_size));
+internal_re->name_count =
+  (pcre_uint16)byteflip(re->name_count, sizeof(re->name_count));
+
+if (study != NULL)
+  {
+  *internal_study = *study;   /* To copy other fields */
+  internal_study->size = byteflip(study->size, sizeof(study->size));
+  internal_study->options = byteflip(study->options, sizeof(study->options));
+  }
+
+return internal_re;
+}
+
+/* End of pcre_tryflipped.c */