]> granicus.if.org Git - php/commitdiff
MFH: Upgrade PCRE lib to 6.7
authorIlia Alshanetsky <iliaa@php.net>
Wed, 30 Aug 2006 20:06:53 +0000 (20:06 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Wed, 30 Aug 2006 20:06:53 +0000 (20:06 +0000)
38 files changed:
ext/pcre/config0.m4
ext/pcre/pcrelib/AUTHORS
ext/pcre/pcrelib/COPYING
ext/pcre/pcrelib/ChangeLog
ext/pcre/pcrelib/LICENCE
ext/pcre/pcrelib/NEWS
ext/pcre/pcrelib/README
ext/pcre/pcrelib/doc/Tech.Notes
ext/pcre/pcrelib/doc/pcre.txt
ext/pcre/pcrelib/pcre.h
ext/pcre/pcrelib/pcre_compile.c
ext/pcre/pcrelib/pcre_exec.c
ext/pcre/pcrelib/pcre_get.c
ext/pcre/pcrelib/pcre_internal.h
ext/pcre/pcrelib/pcre_maketables.c
ext/pcre/pcrelib/pcre_printint.src
ext/pcre/pcrelib/pcre_study.c
ext/pcre/pcrelib/pcre_try_flipped.c
ext/pcre/pcrelib/pcre_ucp_searchfuncs.c
ext/pcre/pcrelib/pcrecpp.cc
ext/pcre/pcrelib/pcrecpp_unittest.cc
ext/pcre/pcrelib/pcredemo.c
ext/pcre/pcrelib/pcregrep.c
ext/pcre/pcrelib/pcreposix.c
ext/pcre/pcrelib/pcretest.c
ext/pcre/pcrelib/testdata/grepinputx
ext/pcre/pcrelib/testdata/testinput1
ext/pcre/pcrelib/testdata/testinput2
ext/pcre/pcrelib/testdata/testinput4
ext/pcre/pcrelib/testdata/testinput5
ext/pcre/pcrelib/testdata/testinput6
ext/pcre/pcrelib/testdata/testinput7
ext/pcre/pcrelib/testdata/testoutput1
ext/pcre/pcrelib/testdata/testoutput2
ext/pcre/pcrelib/testdata/testoutput4
ext/pcre/pcrelib/testdata/testoutput5
ext/pcre/pcrelib/testdata/testoutput6
ext/pcre/pcrelib/testdata/testoutput7

index c48aff0f49443817387a5d2c9dd5a8e021d27082..cb51d0729d14a80d0570650e73c19c9d7e339417 100644 (file)
@@ -13,7 +13,7 @@ PHP_ARG_WITH(pcre-regex,for PCRE support,
 
 if test "$PHP_PCRE_REGEX" != "no"; then
   if test "$PHP_PCRE_REGEX" = "yes"; then
-    PHP_NEW_EXTENSION(pcre, pcrelib/pcre_chartables.c pcrelib/pcre_ucp_searchfuncs.c pcrelib/pcre_compile.c pcrelib/pcre_config.c pcrelib/pcre_dfa_exec.c pcrelib/pcre_exec.c pcrelib/pcre_fullinfo.c pcrelib/pcre_get.c pcrelib/pcre_globals.c pcrelib/pcre_info.c pcrelib/pcre_maketables.c pcrelib/pcre_ord2utf8.c pcrelib/pcre_refcount.c pcrelib/pcre_study.c pcrelib/pcre_tables.c pcrelib/pcre_try_flipped.c pcrelib/pcre_valid_utf8.c pcrelib/pcre_version.c pcrelib/pcre_xclass.c php_pcre.c, $ext_shared,,-DEXPORT= -DNEWLINE=10 -DSUPPORT_UTF8 -DSUPPORT_UCP -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -DMATCH_LIMIT=10000000 -DMATCH_LIMIT_RECURSION=10000000 -I@ext_srcdir@/pcrelib)
+    PHP_NEW_EXTENSION(pcre, pcrelib/pcre_chartables.c pcrelib/pcre_ucp_searchfuncs.c pcrelib/pcre_compile.c pcrelib/pcre_config.c pcrelib/pcre_dfa_exec.c pcrelib/pcre_exec.c pcrelib/pcre_fullinfo.c pcrelib/pcre_get.c pcrelib/pcre_globals.c pcrelib/pcre_info.c pcrelib/pcre_maketables.c pcrelib/pcre_ord2utf8.c pcrelib/pcre_refcount.c pcrelib/pcre_study.c pcrelib/pcre_tables.c pcrelib/pcre_try_flipped.c pcrelib/pcre_valid_utf8.c pcrelib/pcre_version.c pcrelib/pcre_xclass.c php_pcre.c, $ext_shared,,-DEXPORT= -DNEWLINE=10 -DSUPPORT_UTF8 -DSUPPORT_UCP -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -DMATCH_LIMIT=10000000 -DMATCH_LIMIT_RECURSION=10000000 -DMAX_NAME_SIZE=32 -DMAX_NAME_COUNT=10000 -DMAX_DUPLENGTH=30000 -I@ext_srcdir@/pcrelib)
     PHP_ADD_BUILD_DIR($ext_builddir/pcrelib)
     AC_DEFINE(HAVE_BUNDLED_PCRE, 1, [ ])
   else
@@ -50,7 +50,7 @@ if test "$PHP_PCRE_REGEX" != "no"; then
     
     AC_DEFINE(HAVE_PCRE, 1, [ ])
     PHP_ADD_INCLUDE($PCRE_INCDIR)
-    PHP_NEW_EXTENSION(pcre, php_pcre.c, $ext_shared,,-DEXPORT= -DNEWLINE=10 -DSUPPORT_UTF8 -DSUPPORT_UCP -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -DMATCH_LIMIT=10000000 -DMATCH_LIMIT_RECURSION=10000000)
+    PHP_NEW_EXTENSION(pcre, php_pcre.c, $ext_shared,,-DEXPORT= -DNEWLINE=10 -DSUPPORT_UTF8 -DSUPPORT_UCP -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -DMATCH_LIMIT=10000000 -DMATCH_LIMIT_RECURSION=10000000 -DMAX_NAME_SIZE=32 -DMAX_NAME_COUNT=10000 -DMAX_DUPLENGTH=30000)
   fi
   PHP_SUBST(PCRE_SHARED_LIBADD)
 fi
index 33df90f8df3e5db4e40284bc8ec55ba8add6aaf7..adb4fc4019dc9155ef92cd4ad3fe93850508173f 100644 (file)
@@ -8,7 +8,7 @@ Email domain:     cam.ac.uk
 University of Cambridge Computing Service,
 Cambridge, England. Phone: +44 1223 334714.
 
-Copyright (c) 1997-2005 University of Cambridge
+Copyright (c) 1997-2006 University of Cambridge
 All rights reserved
 
 
@@ -17,7 +17,7 @@ THE C++ WRAPPER LIBRARY
 
 Written by:       Google Inc.
 
-Copyright (c) 2005 Google Inc
+Copyright (c) 2006 Google Inc
 All rights reserved
 
 ####
index e8eb0d9370321dca0b8b0ee34223ab38826592f6..daea2e48a3f06cf8039a58e8d5414ed9236667bb 100644 (file)
@@ -22,7 +22,7 @@ Email domain:     cam.ac.uk
 University of Cambridge Computing Service,
 Cambridge, England. Phone: +44 1223 334714.
 
-Copyright (c) 1997-2005 University of Cambridge
+Copyright (c) 1997-2006 University of Cambridge
 All rights reserved.
 
 
@@ -31,7 +31,7 @@ THE C++ WRAPPER FUNCTIONS
 
 Contributed by:   Google Inc.
 
-Copyright (c) 2005, Google Inc.
+Copyright (c) 2006, Google Inc.
 All rights reserved.
 
 
index ce2b358534e22528e391e9f7e7124d55907b0457..2a141348482c135cb17a74f6e3a408c9015c314e 100644 (file)
@@ -1,6 +1,175 @@
 ChangeLog for PCRE
 ------------------
 
+Version 6.7 04-Jul-06
+---------------------
+
+ 1. In order to handle tests when input lines are enormously long, pcretest has
+    been re-factored so that it automatically extends its buffers when
+    necessary. The code is crude, but this _is_ just a test program. The
+    default size has been increased from 32K to 50K.
+
+ 2. The code in pcre_study() was using the value of the re argument before
+    testing it for NULL. (Of course, in any sensible call of the function, it
+    won't be NULL.)
+
+ 3. The memmove() emulation function in pcre_internal.h, which is used on
+    systems that lack both memmove() and bcopy() - that is, hardly ever -
+    was missing a "static" storage class specifier.
+
+ 4. When UTF-8 mode was not set, PCRE looped when compiling certain patterns
+    containing an extended class (one that cannot be represented by a bitmap
+    because it contains high-valued characters or Unicode property items, e.g.
+    [\pZ]). Almost always one would set UTF-8 mode when processing such a
+    pattern, but PCRE should not loop if you do not (it no longer does).
+    [Detail: two cases were found: (a) a repeated subpattern containing an
+    extended class; (b) a recursive reference to a subpattern that followed a
+    previous extended class. It wasn't skipping over the extended class
+    correctly when UTF-8 mode was not set.]
+
+ 5. A negated single-character class was not being recognized as fixed-length
+    in lookbehind assertions such as (?<=[^f]), leading to an incorrect
+    compile error "lookbehind assertion is not fixed length".
+
+ 6. The RunPerlTest auxiliary script was showing an unexpected difference
+    between PCRE and Perl for UTF-8 tests. It turns out that it is hard to
+    write a Perl script that can interpret lines of an input file either as
+    byte characters or as UTF-8, which is what "perltest" was being required to
+    do for the non-UTF-8 and UTF-8 tests, respectively. Essentially what you
+    can't do is switch easily at run time between having the "use utf8;" pragma
+    or not. In the end, I fudged it by using the RunPerlTest script to insert
+    "use utf8;" explicitly for the UTF-8 tests.
+
+ 7. In multiline (/m) mode, PCRE was matching ^ after a terminating newline at
+    the end of the subject string, contrary to the documentation and to what
+    Perl does. This was true of both matching functions. Now it matches only at
+    the start of the subject and immediately after *internal* newlines.
+
+ 8. A call of pcre_fullinfo() from pcretest to get the option bits was passing
+    a pointer to an int instead of a pointer to an unsigned long int. This
+    caused problems on 64-bit systems.
+
+ 9. Applied a patch from the folks at Google to pcrecpp.cc, to fix "another
+    instance of the 'standard' template library not being so standard".
+
+10. There was no check on the number of named subpatterns nor the maximum
+    length of a subpattern name. The product of these values is used to compute
+    the size of the memory block for a compiled pattern. By supplying a very
+    long subpattern name and a large number of named subpatterns, the size
+    computation could be caused to overflow. This is now prevented by limiting
+    the length of names to 32 characters, and the number of named subpatterns
+    to 10,000.
+
+11. Subpatterns that are repeated with specific counts have to be replicated in
+    the compiled pattern. The size of memory for this was computed from the
+    length of the subpattern and the repeat count. The latter is limited to
+    65535, but there was no limit on the former, meaning that integer overflow
+    could in principle occur. The compiled length of a repeated subpattern is
+    now limited to 30,000 bytes in order to prevent this.
+
+12. Added the optional facility to have named substrings with the same name.
+
+13. Added the ability to use a named substring as a condition, using the
+    Python syntax: (?(name)yes|no). This overloads (?(R)... and names that
+    are numbers (not recommended). Forward references are permitted.
+
+14. Added forward references in named backreferences (if you see what I mean).
+
+15. In UTF-8 mode, with the PCRE_DOTALL option set, a quantified dot in the
+    pattern could run off the end of the subject. For example, the pattern
+    "(?s)(.{1,5})"8 did this with the subject "ab".
+
+16. If PCRE_DOTALL or PCRE_MULTILINE were set, pcre_dfa_exec() behaved as if
+    PCRE_CASELESS was set when matching characters that were quantified with ?
+    or *.
+
+17. A character class other than a single negated character that had a minimum
+    but no maximum quantifier - for example [ab]{6,} - was not handled
+    correctly by pce_dfa_exec(). It would match only one character.
+
+18. A valid (though odd) pattern that looked like a POSIX character
+    class but used an invalid character after [ (for example [[,abc,]]) caused
+    pcre_compile() to give the error "Failed: internal error: code overflow" or
+    in some cases to crash with a glibc free() error. This could even happen if
+    the pattern terminated after [[ but there just happened to be a sequence of
+    letters, a binary zero, and a closing ] in the memory that followed.
+
+19. Perl's treatment of octal escapes in the range \400 to \777 has changed
+    over the years. Originally (before any Unicode support), just the bottom 8
+    bits were taken. Thus, for example, \500 really meant \100. Nowadays the
+    output from "man perlunicode" includes this:
+
+      The regular expression compiler produces polymorphic opcodes.  That
+      is, the pattern adapts to the data and automatically switches to
+      the Unicode character scheme when presented with Unicode data--or
+      instead uses a traditional byte scheme when presented with byte
+      data.
+
+    Sadly, a wide octal escape does not cause a switch, and in a string with
+    no other multibyte characters, these octal escapes are treated as before.
+    Thus, in Perl, the pattern  /\500/ actually matches \100 but the pattern
+    /\500|\x{1ff}/ matches \500 or \777 because the whole thing is treated as a
+    Unicode string.
+
+    I have not perpetrated such confusion in PCRE. Up till now, it took just
+    the bottom 8 bits, as in old Perl. I have now made octal escapes with
+    values greater than \377 illegal in non-UTF-8 mode. In UTF-8 mode they
+    translate to the appropriate multibyte character.
+
+29. Applied some refactoring to reduce the number of warnings from Microsoft
+    and Borland compilers. This has included removing the fudge introduced
+    seven years ago for the OS/2 compiler (see 2.02/2 below) because it caused
+    a warning about an unused variable.
+
+21. PCRE has not included VT (character 0x0b) in the set of whitespace
+    characters since release 4.0, because Perl (from release 5.004) does not.
+    [Or at least, is documented not to: some releases seem to be in conflict
+    with the documentation.] However, when a pattern was studied with
+    pcre_study() and all its branches started with \s, PCRE still included VT
+    as a possible starting character. Of course, this did no harm; it just
+    caused an unnecessary match attempt.
+
+22. Removed a now-redundant internal flag bit that recorded the fact that case
+    dependency changed within the pattern. This was once needed for "required
+    byte" processing, but is no longer used. This recovers a now-scarce options
+    bit. Also moved the least significant internal flag bit to the most-
+    significant bit of the word, which was not previously used (hangover from
+    the days when it was an int rather than a uint) to free up another bit for
+    the future.
+
+23. Added support for CRLF line endings as well as CR and LF. As well as the
+    default being selectable at build time, it can now be changed at runtime
+    via the PCRE_NEWLINE_xxx flags. There are now options for pcregrep to
+    specify that it is scanning data with non-default line endings.
+
+24. Changed the definition of CXXLINK to make it agree with the definition of
+    LINK in the Makefile, by replacing LDFLAGS to CXXFLAGS.
+
+25. Applied Ian Taylor's patches to avoid using another stack frame for tail
+    recursions. This makes a big different to stack usage for some patterns.
+
+26. If a subpattern containing a named recursion or subroutine reference such
+    as (?P>B) was quantified, for example (xxx(?P>B)){3}, the calculation of
+    the space required for the compiled pattern went wrong and gave too small a
+    value. Depending on the environment, this could lead to "Failed: internal
+    error: code overflow at offset 49" or "glibc detected double free or
+    corruption" errors.
+
+27. Applied patches from Google (a) to support the new newline modes and (b) to
+    advance over multibyte UTF-8 characters in GlobalReplace.
+
+28. Change free() to pcre_free() in pcredemo.c. Apparently this makes a
+    difference for some implementation of PCRE in some Windows version.
+
+29. Added some extra testing facilities to pcretest:
+
+    \q<number>   in a data line sets the "match limit" value
+    \Q<number>   in a data line sets the "match recursion limt" value
+    -S <number>  sets the stack size, where <number> is in megabytes
+
+    The -S option isn't available for Windows.
+
+
 Version 6.6 06-Feb-06
 ---------------------
 
index 2a3d00e0bcc1ed0f28ca6e0dfc213adc2e0d8eb5..daea2e48a3f06cf8039a58e8d5414ed9236667bb 100644 (file)
@@ -31,7 +31,7 @@ THE C++ WRAPPER FUNCTIONS
 
 Contributed by:   Google Inc.
 
-Copyright (c) 2005, Google Inc.
+Copyright (c) 2006, Google Inc.
 All rights reserved.
 
 
index a8b3a7a04aae4d04a16966ef091013f304cecfff..4f17b198a0a114ee922f3fc7ec4e0c120fcfd010 100644 (file)
@@ -1,6 +1,17 @@
 News about PCRE releases
 ------------------------
 
+Release 6.7 04-Jul-06
+---------------------
+
+The main additions to this release are the ability to use the same name for
+multiple sets of parentheses, and support for CRLF line endings in both the
+library and pcregrep (and in pcretest for testing).
+
+Thanks to Ian Taylor, the stack usage for many kinds of pattern has been
+significantly reduced for certain subject strings.
+
+
 Release 6.5 01-Feb-06
 ---------------------
 
index ab9ee516fe430f3fefab8d3ebb8cf156aee6a507..24d0b9749730c14998cdc40c075f36a0a575960d 100644 (file)
@@ -34,7 +34,7 @@ Documentation for PCRE
 ----------------------
 
 If you install PCRE in the normal way, you will end up with an installed set of
-man pages whose names all start with "pcre". The one that is called "pcre"
+man pages whose names all start with "pcre". The one that is just called "pcre"
 lists all the others. In addition to these man pages, the PCRE documentation is
 supplied in two other forms; however, as there is no standard place to install
 them, they are left in the doc directory of the unpacked source distribution.
@@ -114,15 +114,17 @@ library. You can read more about them in the pcrebuild man page.
 . If, in addition to support for UTF-8 character strings, you want to include
   support for the \P, \p, and \X sequences that recognize Unicode character
   properties, you must add --enable-unicode-properties to the "configure"
-  command. This adds about 90K to the size of the library (in the form of a
+  command. This adds about 30K to the size of the library (in the form of a
   property table); only the basic two-letter properties such as Lu are
   supported.
 
-. You can build PCRE to recognize either CR or LF as the newline character,
-  instead of whatever your compiler uses for "\n", by adding --newline-is-cr or
-  --newline-is-lf to the "configure" command, respectively. Only do this if you
-  really understand what you are doing. On traditional Unix-like systems, the
-  newline character is LF.
+. You can build PCRE to recognize either CR or LF or the sequence CRLF as
+  indicating the end of a line. Whatever you specify at build time is the
+  default; the caller of PCRE can change the selection at run time. The default
+  newline indicator is a single LF character (the Unix standard). You can
+  specify the default newline indicator by adding --newline-is-cr or
+  --newline-is-lf or --newline-is-crlf to the "configure" command,
+  respectively.
 
 . When called via the POSIX interface, PCRE uses malloc() to get additional
   storage for processing capturing parentheses if there are more than 10 of
@@ -142,6 +144,16 @@ library. You can read more about them in the pcrebuild man page.
   pcre_exec() can supply their own value. There is discussion on the pcreapi
   man page.
 
+. There is a separate counter that limits the depth of recursive function calls
+  during a matching process. This also has a default of ten million, which is
+  essentially "unlimited". You can change the default by setting, for example,
+
+  --with-match-limit-recursion=500000
+
+  Recursive function calls use up the runtime stack; running out of stack can
+  cause programs to crash in strange ways. There is a discussion about stack
+  sizes in the pcrestack man page.
+
 . The default maximum compiled pattern size is around 64K. You can increase
   this by adding --with-link-size=3 to the "configure" command. You can
   increase it even more by setting --with-link-size=4, but this is unlikely
@@ -165,7 +177,6 @@ library. You can read more about them in the pcrebuild man page.
 
 The "configure" script builds eight files for the basic C library:
 
-. pcre.h is the header file for C programs that call PCRE
 . Makefile is the makefile that builds the library
 . config.h contains build-time configuration options for the library
 . pcre-config is a script that shows the settings of "configure" options
@@ -432,25 +443,24 @@ The distribution should contain the following files:
   pcre_info.c           )
   pcre_maketables.c     )
   pcre_ord2utf8.c       )
-  pcre_printint.c       )
+  pcre_refcount.c       )
   pcre_study.c          )
   pcre_tables.c         )
   pcre_try_flipped.c    )
-  pcre_ucp_findchar.c   )
+  pcre_ucp_searchfuncs.c)
   pcre_valid_utf8.c     )
   pcre_version.c        )
   pcre_xclass.c         )
-
-  ucp_findchar.c        )
-  ucp.h                 ) source for the code that is used for
-  ucpinternal.h         )   Unicode property handling
   ucptable.c            )
-  ucptypetable.c        )
 
-  pcre.in               "source" for the header for the external API; pcre.h
-                          is built from this by "configure"
+  pcre_printint.src     ) debugging function that is #included in pcretest, and
+                        )   can also be #included in pcre_compile()
+
+  pcre.h                the public PCRE header file
   pcreposix.h           header for the external POSIX wrapper API
   pcre_internal.h       header for internal use
+  ucp.h                 ) headers concerned with
+  ucpinternal.h         )   Unicode property handling
   config.in             template for config.h, which is built by configure
 
   pcrecpp.h             the header file for the C++ wrapper
@@ -477,8 +487,9 @@ The distribution should contain the following files:
   RunGrepTest.in        template for a Unix shell script for pcregrep tests
   config.guess          ) files used by libtool,
   config.sub            )   used only when building a shared library
+  config.h.in           "source" for the config.h header file
   configure             a configuring shell script (built by autoconf)
-  configure.in          the autoconf input used to build configure
+  configure.ac          the autoconf input used to build configure
   doc/Tech.Notes        notes on the encoding
   doc/*.3               man page sources for the PCRE functions
   doc/*.1               man page sources for pcregrep and pcretest
@@ -506,7 +517,6 @@ The distribution should contain the following files:
 
   libpcre.def
   libpcreposix.def
-  pcre.def
 
 (D) Auxiliary file for VPASCAL
 
@@ -515,4 +525,4 @@ The distribution should contain the following files:
 Philip Hazel
 Email local part: ph10
 Email domain: cam.ac.uk
-January 2006
+June 2006
index aa5398d0faacd5e83e9475a6c3412f350ad079cf..21dbe1f9b53c8e5fd8acfcf0b7379f0c47e8a717 100644 (file)
@@ -1,6 +1,9 @@
 Technical Notes about PCRE
 --------------------------
 
+These are very rough technical notes that record potentially useful information 
+about PCRE internals.
+
 Historical note 1
 -----------------
 
@@ -21,13 +24,14 @@ the pattern, as is expected in Unix and Perl-style regular expressions.
 Historical note 2
 -----------------
 
-By contrast, the code originally written by Henry Spencer and subsequently
-heavily modified for Perl actually compiles the expression twice: once in a
-dummy mode in order to find out how much store will be needed, and then for
-real. The execution function operates by backtracking and maximizing (or,
-optionally, minimizing in Perl) the amount of the subject that matches
-individual wild portions of the pattern. This is an "NFA algorithm" in Friedl's
-terminology.
+By contrast, the code originally written by Henry Spencer (which was
+subsequently heavily modified for Perl) compiles the expression twice: once in
+a dummy mode in order to find out how much store will be needed, and then for
+real. (The Perl version probably doesn't do this any more; I'm talking about
+the original library.) The execution function operates by backtracking and
+maximizing (or, optionally, minimizing in Perl) the amount of the subject that
+matches individual wild portions of the pattern. This is an "NFA algorithm" in
+Friedl's terminology.
 
 OK, here's the real stuff
 -------------------------
@@ -43,7 +47,7 @@ then a second pass to do the real compile - which may use a bit less than the
 predicted amount of store. The idea is that this is going to turn out faster
 because the first pass is degenerate and the second pass can just store stuff
 straight into the vector, which it knows is big enough. It does make the
-compiling functions bigger, of course, but they have got quite big anyway to
+compiling functions bigger, of course, but they have become quite big anyway to
 handle all the Perl stuff.
 
 Traditional matching function
@@ -63,7 +67,7 @@ pcre_dfa_exec(). This implements a DFA matching algorithm that searches
 simultaneously for all possible matches that start at one point in the subject 
 string. (Going back to my roots: see Historical Note 1 above.) This function 
 intreprets the same compiled pattern data as pcre_exec(); however, not all the 
-facilities are available, and those that are don't always work in quite the 
+facilities are available, and those that are do not always work in quite the 
 same way. See the user documentation for details.
 
 Format of compiled patterns
@@ -157,10 +161,12 @@ Match by Unicode property
 
 OP_PROP and OP_NOTPROP are used for positive and negative matches of a 
 character by testing its Unicode property (the \p and \P escape sequences).
-Each is followed by a single byte that encodes the desired property value.
+Each is followed by two bytes that encode the desired property as a type and a 
+value.
 
-Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by two 
-bytes: OP_PROP or OP_NOTPROP and then the desired property value.
+Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by 
+three bytes: OP_PROP or OP_NOTPROP and then the desired property type and 
+value.
 
 
 Matching literal characters
@@ -339,4 +345,4 @@ at compile time, and so does not cause anything to be put into the compiled
 data.
 
 Philip Hazel
-January 2006
+June 2006
index fe57de47313427f8e055453cce10f4a65693796c..d6c204b5744da9da6d6b08a2429ce35903937df2 100644 (file)
@@ -81,6 +81,7 @@ USER DOCUMENTATION
          pcreposix         the POSIX-compatible C API
          pcreprecompile    details of saving and re-using precompiled patterns
          pcresample        discussion of the sample program
+         pcrestack         discussion of stack usage
          pcretest          description of the pcretest testing command
 
        In  addition,  in the "man" and HTML formats, there is a short page for
@@ -100,19 +101,24 @@ LIMITATIONS
        In these cases the limit is substantially larger.  However,  the  speed
        of execution will be slower.
 
-       All values in repeating quantifiers must be less than 65536.  The maxi-
-       mum number of capturing subpatterns is 65535.
+       All  values in repeating quantifiers must be less than 65536. The maxi-
+       mum compiled length of subpattern with  an  explicit  repeat  count  is
+       30000 bytes. The maximum number of capturing subpatterns is 65535.
 
-       There is no limit to the number of non-capturing subpatterns,  but  the
-       maximum  depth  of  nesting  of  all kinds of parenthesized subpattern,
+       There  is  no limit to the number of non-capturing subpatterns, but the
+       maximum depth of nesting of  all  kinds  of  parenthesized  subpattern,
        including capturing subpatterns, assertions, and other types of subpat-
        tern, is 200.
 
+       The maximum length of name for a named subpattern is 32, and the  maxi-
+       mum number of named subpatterns is 10000.
+
        The  maximum  length of a subject string is the largest positive number
        that an integer variable can hold. However, when using the  traditional
        matching function, PCRE uses recursion to handle subpatterns and indef-
        inite repetition.  This means that the available stack space may  limit
        the size of a subject string that can be processed by certain patterns.
+       For a discussion of stack issues, see the pcrestack documentation.
 
 
 UTF-8 AND UNICODE PROPERTY SUPPORT
@@ -162,37 +168,40 @@ UTF-8 AND UNICODE PROPERTY SUPPORT
        2. An unbraced hexadecimal escape sequence (such  as  \xb3)  matches  a
        two-byte UTF-8 character if the value is greater than 127.
 
-       3.  Repeat quantifiers apply to complete UTF-8 characters, not to indi-
+       3.  Octal  numbers  up to \777 are recognized, and match two-byte UTF-8
+       characters for values greater than \177.
+
+       4. Repeat quantifiers apply to complete UTF-8 characters, not to  indi-
        vidual bytes, for example: \x{100}{3}.
 
-       4. The dot metacharacter matches one UTF-8 character instead of a  sin-
+       5.  The dot metacharacter matches one UTF-8 character instead of a sin-
        gle byte.
 
-       5.  The  escape sequence \C can be used to match a single byte in UTF-8
-       mode, but its use can lead to some strange effects.  This  facility  is
+       6. The escape sequence \C can be used to match a single byte  in  UTF-8
+       mode,  but  its  use can lead to some strange effects. This facility is
        not available in the alternative matching function, pcre_dfa_exec().
 
-       6.  The  character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly
-       test characters of any code value, but the characters that PCRE  recog-
-       nizes  as  digits,  spaces,  or  word characters remain the same set as
+       7. The character escapes \b, \B, \d, \D, \s, \S, \w, and  \W  correctly
+       test  characters of any code value, but the characters that PCRE recog-
+       nizes as digits, spaces, or word characters  remain  the  same  set  as
        before, all with values less than 256. This remains true even when PCRE
-       includes  Unicode  property support, because to do otherwise would slow
-       down PCRE in many common cases. If you really want to test for a  wider
-       sense  of,  say,  "digit",  you must use Unicode property tests such as
+       includes Unicode property support, because to do otherwise  would  slow
+       down  PCRE in many common cases. If you really want to test for a wider
+       sense of, say, "digit", you must use Unicode  property  tests  such  as
        \p{Nd}.
 
-       7. Similarly, characters that match the POSIX named  character  classes
+       8.  Similarly,  characters that match the POSIX named character classes
        are all low-valued characters.
 
-       8.  Case-insensitive  matching  applies only to characters whose values
-       are less than 128, unless PCRE is built with Unicode property  support.
-       Even  when  Unicode  property support is available, PCRE still uses its
-       own character tables when checking the case of  low-valued  characters,
-       so  as not to degrade performance.  The Unicode property information is
+       9. Case-insensitive matching applies only to  characters  whose  values
+       are  less than 128, unless PCRE is built with Unicode property support.
+       Even when Unicode property support is available, PCRE  still  uses  its
+       own  character  tables when checking the case of low-valued characters,
+       so as not to degrade performance.  The Unicode property information  is
        used only for characters with higher values. Even when Unicode property
        support is available, PCRE supports case-insensitive matching only when
-       there is a one-to-one mapping between a letter's  cases.  There  are  a
-       small  number  of  many-to-one  mappings in Unicode; these are not sup-
+       there  is  a  one-to-one  mapping between a letter's cases. There are a
+       small number of many-to-one mappings in Unicode;  these  are  not  sup-
        ported by PCRE.
 
 
@@ -202,11 +211,11 @@ AUTHOR
        University Computing Service,
        Cambridge CB2 3QG, England.
 
-       Putting an actual email address here seems to have been a spam  magnet,
+       Putting  an actual email address here seems to have been a spam magnet,
        so I've taken it away. If you want to email me, use my initial and sur-
        name, separated by a dot, at the domain ucs.cam.ac.uk.
 
-Last updated: 24 January 2006
+Last updated: 05 June 2006
 Copyright (c) 1997-2006 University of Cambridge.
 ------------------------------------------------------------------------------
 
@@ -281,15 +290,25 @@ UNICODE CHARACTER PROPERTY SUPPORT
 
 CODE VALUE OF NEWLINE
 
-       By default, PCRE treats character 10 (linefeed) as the newline  charac-
-       ter. This is the normal newline character on Unix-like systems. You can
-       compile PCRE to use character 13 (carriage return) instead by adding
+       By default, PCRE interprets character 10 (linefeed, LF)  as  indicating
+       the  end  of  a line. This is the normal newline character on Unix-like
+       systems. You can compile PCRE to use character 13 (carriage return, CR)
+       instead, by adding
 
          --enable-newline-is-cr
 
-       to the configure command. For completeness there is  also  a  --enable-
-       newline-is-lf  option,  which explicitly specifies linefeed as the new-
-       line character.
+       to  the  configure  command.  There  is  also  a --enable-newline-is-lf
+       option, which explicitly specifies linefeed as the newline character.
+
+       Alternatively, you can specify that line endings are to be indicated by
+       the two character sequence CRLF. If you want this, add
+
+         --enable-newline-is-crlf
+
+       to  the  configure command. Whatever line ending convention is selected
+       when PCRE is built can be overridden when  the  library  functions  are
+       called.  At  build time it is conventional to use the standard for your
+       operating system.
 
 
 BUILDING SHARED AND STATIC LIBRARIES
@@ -320,23 +339,6 @@ POSIX MALLOC USAGE
        to the configure command.
 
 
-LIMITING PCRE RESOURCE USAGE
-
-       Internally,  PCRE has a function called match(), which it calls repeat-
-       edly  (possibly  recursively)  when  matching  a   pattern   with   the
-       pcre_exec()  function.  By controlling the maximum number of times this
-       function may be called during a single matching operation, a limit  can
-       be  placed  on  the resources used by a single call to pcre_exec(). The
-       limit can be changed at run time, as described in the pcreapi  documen-
-       tation.  The default is 10 million, but this can be changed by adding a
-       setting such as
-
-         --with-match-limit=500000
-
-       to  the  configure  command.  This  setting  has  no  effect   on   the
-       pcre_dfa_exec() matching function.
-
-
 HANDLING VERY LARGE PATTERNS
 
        Within  a  compiled  pattern,  offset values are used to point from one
@@ -366,10 +368,12 @@ AVOIDING EXCESSIVE STACK USAGE
        ing by making recursive calls to an internal function  called  match().
        In  environments  where  the size of the stack is limited, this can se-
        verely limit PCRE's operation. (The Unix environment does  not  usually
-       suffer  from  this  problem.)  An alternative approach that uses memory
-       from the heap to remember data, instead  of  using  recursive  function
-       calls,  has been implemented to work round this problem. If you want to
-       build a version of PCRE that works this way, add
+       suffer from this problem, but it may sometimes be necessary to increase
+       the maximum stack size.  There is a discussion in the  pcrestack  docu-
+       mentation.)  An alternative approach to recursion that uses memory from
+       the heap to remember data, instead of using recursive  function  calls,
+       has  been  implemented to work round the problem of limited stack size.
+       If you want to build a version of PCRE that works this way, add
 
          --disable-stack-for-recursion
 
@@ -384,19 +388,49 @@ AVOIDING EXCESSIVE STACK USAGE
        function; it is not relevant for the the pcre_dfa_exec() function.
 
 
+LIMITING PCRE RESOURCE USAGE
+
+       Internally, PCRE has a function called match(), which it calls  repeat-
+       edly   (sometimes   recursively)  when  matching  a  pattern  with  the
+       pcre_exec() function. By controlling the maximum number of  times  this
+       function  may be called during a single matching operation, a limit can
+       be placed on the resources used by a single call  to  pcre_exec().  The
+       limit  can be changed at run time, as described in the pcreapi documen-
+       tation. The default is 10 million, but this can be changed by adding  a
+       setting such as
+
+         --with-match-limit=500000
+
+       to   the   configure  command.  This  setting  has  no  effect  on  the
+       pcre_dfa_exec() matching function.
+
+       In some environments it is desirable to limit the  depth  of  recursive
+       calls of match() more strictly than the total number of calls, in order
+       to restrict the maximum amount of stack (or heap,  if  --disable-stack-
+       for-recursion is specified) that is used. A second limit controls this;
+       it defaults to the value that  is  set  for  --with-match-limit,  which
+       imposes  no  additional constraints. However, you can set a lower limit
+       by adding, for example,
+
+         --with-match-limit-recursion=10000
+
+       to the configure command. This value can  also  be  overridden  at  run
+       time.
+
+
 USING EBCDIC CODE
 
-       PCRE assumes by default that it will run in an  environment  where  the
-       character  code  is  ASCII  (or Unicode, which is a superset of ASCII).
-       PCRE can, however, be compiled to  run  in  an  EBCDIC  environment  by
+       PCRE  assumes  by  default that it will run in an environment where the
+       character code is ASCII (or Unicode, which is  a  superset  of  ASCII).
+       PCRE  can,  however,  be  compiled  to  run in an EBCDIC environment by
        adding
 
          --enable-ebcdic
 
        to the configure command.
 
-Last updated: 15 August 2005
-Copyright (c) 1997-2005 University of Cambridge.
+Last updated: 06 June 2006
+Copyright (c) 1997-2006 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -441,9 +475,9 @@ REGULAR EXPRESSIONS AS TREES
        resented  as  a  tree structure. An unlimited repetition in the pattern
        makes the tree of infinite size, but it is still a tree.  Matching  the
        pattern  to a given subject string (from a given starting point) can be
-       thought of as a search of the tree.  There are  two  standard  ways  to
-       search  a  tree: depth-first and breadth-first, and these correspond to
-       the two matching algorithms provided by PCRE.
+       thought of as a search of the tree.  There are two  ways  to  search  a
+       tree:  depth-first  and  breadth-first, and these correspond to the two
+       matching algorithms provided by PCRE.
 
 
 THE STANDARD MATCHING ALGORITHM
@@ -563,8 +597,8 @@ DISADVANTAGES OF THE DFA ALGORITHM
        but  does not provide the advantage that it does for the standard algo-
        rithm.
 
-Last updated: 28 February 2005
-Copyright (c) 1997-2005 University of Cambridge.
+Last updated: 06 June 2006
+Copyright (c) 1997-2006 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -617,6 +651,9 @@ PCRE NATIVE API
        int pcre_get_stringnumber(const pcre *code,
             const char *name);
 
+       int pcre_get_stringtable_entries(const pcre *code,
+            const char *name, char **first, char **last);
+
        int pcre_get_substring(const char *subject, int *ovector,
             int stringcount, int stringnumber,
             const char **stringptr);
@@ -677,11 +714,11 @@ PCRE API OVERVIEW
 
        A second matching function, pcre_dfa_exec(), which is not Perl-compati-
        ble,  is  also provided. This uses a different algorithm for the match-
-       ing. This allows it to find all possible matches (at a given  point  in
-       the  subject),  not  just  one. However, this algorithm does not return
-       captured substrings. A description of the two matching  algorithms  and
-       their  advantages  and disadvantages is given in the pcrematching docu-
-       mentation.
+       ing. The alternative algorithm finds all possible matches (at  a  given
+       point in the subject). However, this algorithm does not return captured
+       substrings. A description of the  two  matching  algorithms  and  their
+       advantages  and  disadvantages  is given in the pcrematching documenta-
+       tion.
 
        In addition to the main compiling and  matching  functions,  there  are
        convenience functions for extracting captured substrings from a subject
@@ -693,6 +730,7 @@ PCRE API OVERVIEW
          pcre_get_named_substring()
          pcre_get_substring_list()
          pcre_get_stringnumber()
+         pcre_get_stringtable_entries()
 
        pcre_free_substring() and pcre_free_substring_list() are also provided,
        to free the memory used for extracted strings.
@@ -724,12 +762,15 @@ PCRE API OVERVIEW
        indirections  to  memory  management functions. These special functions
        are used only when PCRE is compiled to use  the  heap  for  remembering
        data, instead of recursive function calls, when running the pcre_exec()
-       function. This is a non-standard way of building PCRE, for use in envi-
-       ronments that have limited stacks. Because of the greater use of memory
-       management, it runs more slowly.  Separate functions  are  provided  so
-       that  special-purpose  external  code  can  be used for this case. When
-       used, these functions are always called in a  stack-like  manner  (last
-       obtained,  first freed), and always for memory blocks of the same size.
+       function. See the pcrebuild documentation for  details  of  how  to  do
+       this.  It  is  a non-standard way of building PCRE, for use in environ-
+       ments that have limited stacks. Because of the greater  use  of  memory
+       management,  it  runs  more  slowly. Separate functions are provided so
+       that special-purpose external code can be  used  for  this  case.  When
+       used,  these  functions  are always called in a stack-like manner (last
+       obtained, first freed), and always for memory blocks of the same  size.
+       There  is  a discussion about PCRE's stack usage in the pcrestack docu-
+       mentation.
 
        The global variable pcre_callout initially contains NULL. It can be set
        by  the  caller  to  a "callout" function, which PCRE will then call at
@@ -737,14 +778,27 @@ PCRE API OVERVIEW
        pcrecallout documentation.
 
 
+NEWLINES
+       PCRE supports three different conventions for indicating line breaks in
+       strings: a single CR character, a single LF character, or the two-char-
+       acter  sequence  CRLF.  All  three  are used as "standard" by different
+       operating systems.  When PCRE is built, a default can be specified. The
+       default  default  is  LF, which is the Unix standard. When PCRE is run,
+       the default can be overridden, either when a pattern  is  compiled,  or
+       when it is matched.
+
+       In the PCRE documentation the word "newline" is used to mean "the char-
+       acter or pair of characters that indicate a line break".
+
+
 MULTITHREADING
 
-       The  PCRE  functions  can be used in multi-threading applications, with
+       The PCRE functions can be used in  multi-threading  applications,  with
        the  proviso  that  the  memory  management  functions  pointed  to  by
        pcre_malloc, pcre_free, pcre_stack_malloc, and pcre_stack_free, and the
        callout function pointed to by pcre_callout, are shared by all threads.
 
-       The  compiled form of a regular expression is not altered during match-
+       The compiled form of a regular expression is not altered during  match-
        ing, so the same compiled pattern can safely be used by several threads
        at once.
 
@@ -752,8 +806,8 @@ MULTITHREADING
 SAVING PRECOMPILED PATTERNS FOR LATER USE
 
        The compiled form of a regular expression can be saved and re-used at a
-       later time, possibly by a different program, and even on a  host  other
-       than  the  one  on  which  it  was  compiled.  Details are given in the
+       later  time,  possibly by a different program, and even on a host other
+       than the one on which  it  was  compiled.  Details  are  given  in  the
        pcreprecompile documentation.
 
 
@@ -761,68 +815,68 @@ CHECKING BUILD-TIME OPTIONS
 
        int pcre_config(int what, void *where);
 
-       The function pcre_config() makes it possible for a PCRE client to  dis-
+       The  function pcre_config() makes it possible for a PCRE client to dis-
        cover which optional features have been compiled into the PCRE library.
-       The pcrebuild documentation has more details about these optional  fea-
+       The  pcrebuild documentation has more details about these optional fea-
        tures.
 
-       The  first  argument  for pcre_config() is an integer, specifying which
+       The first argument for pcre_config() is an  integer,  specifying  which
        information is required; the second argument is a pointer to a variable
-       into  which  the  information  is  placed. The following information is
+       into which the information is  placed.  The  following  information  is
        available:
 
          PCRE_CONFIG_UTF8
 
-       The output is an integer that is set to one if UTF-8 support is  avail-
+       The  output is an integer that is set to one if UTF-8 support is avail-
        able; otherwise it is set to zero.
 
          PCRE_CONFIG_UNICODE_PROPERTIES
 
-       The  output  is  an  integer  that is set to one if support for Unicode
+       The output is an integer that is set to  one  if  support  for  Unicode
        character properties is available; otherwise it is set to zero.
 
          PCRE_CONFIG_NEWLINE
 
-       The output is an integer that is set to the value of the code  that  is
-       used  for the newline character. It is either linefeed (10) or carriage
-       return (13), and should normally be the  standard  character  for  your
-       operating system.
+       The  output  is  an integer whose value specifies the default character
+       sequence that is recognized as meaning "newline". The three values that
+       are supported are: 10 for LF, 13 for CR, and 3338 for CRLF. The default
+       should normally be the standard sequence for your operating system.
 
          PCRE_CONFIG_LINK_SIZE
 
-       The  output  is  an  integer that contains the number of bytes used for
+       The output is an integer that contains the number  of  bytes  used  for
        internal linkage in compiled regular expressions. The value is 2, 3, or
-       4.  Larger  values  allow larger regular expressions to be compiled, at
-       the expense of slower matching. The default value of  2  is  sufficient
-       for  all  but  the  most massive patterns, since it allows the compiled
+       4. Larger values allow larger regular expressions to  be  compiled,  at
+       the  expense  of  slower matching. The default value of 2 is sufficient
+       for all but the most massive patterns, since  it  allows  the  compiled
        pattern to be up to 64K in size.
 
          PCRE_CONFIG_POSIX_MALLOC_THRESHOLD
 
-       The output is an integer that contains the threshold  above  which  the
-       POSIX  interface  uses malloc() for output vectors. Further details are
+       The  output  is  an integer that contains the threshold above which the
+       POSIX interface uses malloc() for output vectors. Further  details  are
        given in the pcreposix documentation.
 
          PCRE_CONFIG_MATCH_LIMIT
 
        The output is an integer that gives the default limit for the number of
-       internal  matching  function  calls in a pcre_exec() execution. Further
+       internal matching function calls in a  pcre_exec()  execution.  Further
        details are given with pcre_exec() below.
 
          PCRE_CONFIG_MATCH_LIMIT_RECURSION
 
-       The output is an integer that gives the default limit for the depth  of
-       recursion  when calling the internal matching function in a pcre_exec()
+       The  output is an integer that gives the default limit for the depth of
+       recursion when calling the internal matching function in a  pcre_exec()
        execution. Further details are given with pcre_exec() below.
 
          PCRE_CONFIG_STACKRECURSE
 
-       The output is an integer that is set to one if internal recursion  when
+       The  output is an integer that is set to one if internal recursion when
        running pcre_exec() is implemented by recursive function calls that use
-       the stack to remember their state. This is the usual way that  PCRE  is
+       the  stack  to remember their state. This is the usual way that PCRE is
        compiled. The output is zero if PCRE was compiled to use blocks of data
-       on the  heap  instead  of  recursive  function  calls.  In  this  case,
-       pcre_stack_malloc  and  pcre_stack_free  are  called  to  manage memory
+       on  the  heap  instead  of  recursive  function  calls.  In  this case,
+       pcre_stack_malloc and  pcre_stack_free  are  called  to  manage  memory
        blocks on the heap, thus avoiding the use of the stack.
 
 
@@ -839,55 +893,55 @@ COMPILING A PATTERN
 
        Either of the functions pcre_compile() or pcre_compile2() can be called
        to compile a pattern into an internal form. The only difference between
-       the two interfaces is that pcre_compile2() has an additional  argument,
+       the  two interfaces is that pcre_compile2() has an additional argument,
        errorcodeptr, via which a numerical error code can be returned.
 
        The pattern is a C string terminated by a binary zero, and is passed in
-       the pattern argument. A pointer to a single block  of  memory  that  is
-       obtained  via  pcre_malloc is returned. This contains the compiled code
+       the  pattern  argument.  A  pointer to a single block of memory that is
+       obtained via pcre_malloc is returned. This contains the  compiled  code
        and related data. The pcre type is defined for the returned block; this
        is a typedef for a structure whose contents are not externally defined.
-       It is up to the caller  to  free  the  memory  when  it  is  no  longer
-       required.
+       It is up to the caller to free the memory (via pcre_free) when it is no
+       longer required.
 
-       Although  the compiled code of a PCRE regex is relocatable, that is, it
+       Although the compiled code of a PCRE regex is relocatable, that is,  it
        does not depend on memory location, the complete pcre data block is not
-       fully  relocatable, because it may contain a copy of the tableptr argu-
+       fully relocatable, because it may contain a copy of the tableptr  argu-
        ment, which is an address (see below).
 
        The options argument contains independent bits that affect the compila-
-       tion.  It  should  be  zero  if  no options are required. The available
-       options are described below. Some of them, in  particular,  those  that
-       are  compatible  with  Perl,  can also be set and unset from within the
-       pattern (see the detailed description  in  the  pcrepattern  documenta-
-       tion).  For  these options, the contents of the options argument speci-
-       fies their initial settings at the start of compilation and  execution.
-       The  PCRE_ANCHORED option can be set at the time of matching as well as
-       at compile time.
+       tion. It should be zero if  no  options  are  required.  The  available
+       options  are  described  below. Some of them, in particular, those that
+       are compatible with Perl, can also be set and  unset  from  within  the
+       pattern  (see  the  detailed  description in the pcrepattern documenta-
+       tion). For these options, the contents of the options  argument  speci-
+       fies  their initial settings at the start of compilation and execution.
+       The PCRE_ANCHORED and PCRE_NEWLINE_xxx options can be set at  the  time
+       of matching as well as at compile time.
 
        If errptr is NULL, pcre_compile() returns NULL immediately.  Otherwise,
-       if  compilation  of  a  pattern fails, pcre_compile() returns NULL, and
+       if compilation of a pattern fails,  pcre_compile()  returns  NULL,  and
        sets the variable pointed to by errptr to point to a textual error mes-
        sage. This is a static string that is part of the library. You must not
        try to free it. The offset from the start of the pattern to the charac-
        ter where the error was discovered is placed in the variable pointed to
-       by erroffset, which must not be NULL. If it is, an immediate  error  is
+       by  erroffset,  which must not be NULL. If it is, an immediate error is
        given.
 
-       If  pcre_compile2()  is  used instead of pcre_compile(), and the error-
-       codeptr argument is not NULL, a non-zero error code number is  returned
-       via  this argument in the event of an error. This is in addition to the
+       If pcre_compile2() is used instead of pcre_compile(),  and  the  error-
+       codeptr  argument is not NULL, a non-zero error code number is returned
+       via this argument in the event of an error. This is in addition to  the
        textual error message. Error codes and messages are listed below.
 
-       If the final argument, tableptr, is NULL, PCRE uses a  default  set  of
-       character  tables  that  are  built  when  PCRE  is compiled, using the
-       default C locale. Otherwise, tableptr must be an address  that  is  the
-       result  of  a  call to pcre_maketables(). This value is stored with the
-       compiled pattern, and used again by pcre_exec(), unless  another  table
+       If  the  final  argument, tableptr, is NULL, PCRE uses a default set of
+       character tables that are  built  when  PCRE  is  compiled,  using  the
+       default  C  locale.  Otherwise, tableptr must be an address that is the
+       result of a call to pcre_maketables(). This value is  stored  with  the
+       compiled  pattern,  and used again by pcre_exec(), unless another table
        pointer is passed to it. For more discussion, see the section on locale
        support below.
 
-       This code fragment shows a typical straightforward  call  to  pcre_com-
+       This  code  fragment  shows a typical straightforward call to pcre_com-
        pile():
 
          pcre *re;
@@ -900,86 +954,95 @@ COMPILING A PATTERN
            &erroffset,       /* for error offset */
            NULL);            /* use default character tables */
 
-       The  following  names  for option bits are defined in the pcre.h header
+       The following names for option bits are defined in  the  pcre.h  header
        file:
 
          PCRE_ANCHORED
 
        If this bit is set, the pattern is forced to be "anchored", that is, it
-       is  constrained to match only at the first matching point in the string
-       that is being searched (the "subject string"). This effect can also  be
-       achieved  by appropriate constructs in the pattern itself, which is the
+       is constrained to match only at the first matching point in the  string
+       that  is being searched (the "subject string"). This effect can also be
+       achieved by appropriate constructs in the pattern itself, which is  the
        only way to do it in Perl.
 
          PCRE_AUTO_CALLOUT
 
        If this bit is set, pcre_compile() automatically inserts callout items,
-       all  with  number  255, before each pattern item. For discussion of the
+       all with number 255, before each pattern item. For  discussion  of  the
        callout facility, see the pcrecallout documentation.
 
          PCRE_CASELESS
 
-       If this bit is set, letters in the pattern match both upper  and  lower
-       case  letters.  It  is  equivalent  to  Perl's /i option, and it can be
-       changed within a pattern by a (?i) option setting. In UTF-8 mode,  PCRE
-       always  understands the concept of case for characters whose values are
-       less than 128, so caseless matching is always possible. For  characters
-       with  higher  values,  the concept of case is supported if PCRE is com-
-       piled with Unicode property support, but not otherwise. If you want  to
-       use  caseless  matching  for  characters 128 and above, you must ensure
-       that PCRE is compiled with Unicode property support  as  well  as  with
+       If  this  bit is set, letters in the pattern match both upper and lower
+       case letters. It is equivalent to Perl's  /i  option,  and  it  can  be
+       changed  within a pattern by a (?i) option setting. In UTF-8 mode, PCRE
+       always understands the concept of case for characters whose values  are
+       less  than 128, so caseless matching is always possible. For characters
+       with higher values, the concept of case is supported if  PCRE  is  com-
+       piled  with Unicode property support, but not otherwise. If you want to
+       use caseless matching for characters 128 and  above,  you  must  ensure
+       that  PCRE  is  compiled  with Unicode property support as well as with
        UTF-8 support.
 
          PCRE_DOLLAR_ENDONLY
 
-       If  this bit is set, a dollar metacharacter in the pattern matches only
-       at the end of the subject string. Without this option,  a  dollar  also
-       matches  immediately before the final character if it is a newline (but
-       not before any  other  newlines).  The  PCRE_DOLLAR_ENDONLY  option  is
-       ignored if PCRE_MULTILINE is set. There is no equivalent to this option
-       in Perl, and no way to set it within a pattern.
+       If this bit is set, a dollar metacharacter in the pattern matches  only
+       at  the  end  of the subject string. Without this option, a dollar also
+       matches immediately before a newline at the end of the string (but  not
+       before  any  other newlines). The PCRE_DOLLAR_ENDONLY option is ignored
+       if PCRE_MULTILINE is set.  There is no equivalent  to  this  option  in
+       Perl, and no way to set it within a pattern.
 
          PCRE_DOTALL
 
        If this bit is set, a dot metacharater in the pattern matches all char-
-       acters,  including  newlines.  Without  it, newlines are excluded. This
-       option is equivalent to Perl's /s option, and it can be changed  within
-       a  pattern  by  a  (?s)  option  setting. A negative class such as [^a]
-       always matches a newline character, independent of the setting of  this
-       option.
+       acters, including those that indicate newline. Without it, a  dot  does
+       not  match  when  the  current position is at a newline. This option is
+       equivalent to Perl's /s option, and it can be changed within a  pattern
+       by  a (?s) option setting. A negative class such as [^a] always matches
+       newlines, independent of the setting of this option.
+
+         PCRE_DUPNAMES
+
+       If this bit is set, names used to identify capturing  subpatterns  need
+       not be unique. This can be helpful for certain types of pattern when it
+       is known that only one instance of the named  subpattern  can  ever  be
+       matched.  There  are  more details of named subpatterns below; see also
+       the pcrepattern documentation.
 
          PCRE_EXTENDED
 
-       If  this  bit  is  set,  whitespace  data characters in the pattern are
+       If this bit is set, whitespace  data  characters  in  the  pattern  are
        totally ignored except when escaped or inside a character class. White-
        space does not include the VT character (code 11). In addition, charac-
        ters between an unescaped # outside a character class and the next new-
-       line  character,  inclusive,  are  also  ignored. This is equivalent to
-       Perl's /x option, and it can be changed within  a  pattern  by  a  (?x)
-       option setting.
-
-       This  option  makes  it possible to include comments inside complicated
-       patterns.  Note, however, that this applies only  to  data  characters.
-       Whitespace   characters  may  never  appear  within  special  character
-       sequences in a pattern, for  example  within  the  sequence  (?(  which
+       line, inclusive, are also ignored. This  is  equivalent  to  Perl's  /x
+       option,  and  it  can be changed within a pattern by a (?x) option set-
+       ting.
+
+       This option makes it possible to include  comments  inside  complicated
+       patterns.   Note,  however,  that this applies only to data characters.
+       Whitespace  characters  may  never  appear  within  special   character
+       sequences  in  a  pattern,  for  example  within the sequence (?( which
        introduces a conditional subpattern.
 
          PCRE_EXTRA
 
-       This  option  was invented in order to turn on additional functionality
-       of PCRE that is incompatible with Perl, but it  is  currently  of  very
-       little  use. When set, any backslash in a pattern that is followed by a
-       letter that has no special meaning  causes  an  error,  thus  reserving
-       these  combinations  for  future  expansion.  By default, as in Perl, a
-       backslash followed by a letter with no special meaning is treated as  a
-       literal.  There  are  at  present  no other features controlled by this
-       option. It can also be set by a (?X) option setting within a pattern.
+       This option was invented in order to turn on  additional  functionality
+       of  PCRE  that  is  incompatible with Perl, but it is currently of very
+       little use. When set, any backslash in a pattern that is followed by  a
+       letter  that  has  no  special  meaning causes an error, thus reserving
+       these combinations for future expansion. By  default,  as  in  Perl,  a
+       backslash  followed by a letter with no special meaning is treated as a
+       literal. (Perl can, however, be persuaded to give a warning for  this.)
+       There  are  at  present no other features controlled by this option. It
+       can also be set by a (?X) option setting within a pattern.
 
          PCRE_FIRSTLINE
 
        If this option is set, an  unanchored  pattern  is  required  to  match
-       before  or at the first newline character in the subject string, though
-       the matched text may continue over the newline.
+       before  or  at  the  first  newline  in  the subject string, though the
+       matched text may continue over the newline.
 
          PCRE_MULTILINE
 
@@ -991,54 +1054,71 @@ COMPILING A PATTERN
        is set). This is the same as Perl.
 
        When  PCRE_MULTILINE  it  is set, the "start of line" and "end of line"
-       constructs match immediately following or immediately before  any  new-
-       line  in the subject string, respectively, as well as at the very start
-       and end. This is equivalent to Perl's /m option, and it can be  changed
-       within a pattern by a (?m) option setting. If there are no "\n" charac-
-       ters in a subject string, or no occurrences of ^ or  $  in  a  pattern,
+       constructs match immediately following or immediately  before  internal
+       newlines  in  the  subject string, respectively, as well as at the very
+       start and end. This is equivalent to Perl's /m option, and  it  can  be
+       changed within a pattern by a (?m) option setting. If there are no new-
+       lines in a subject string, or no occurrences of ^ or $  in  a  pattern,
        setting PCRE_MULTILINE has no effect.
 
+         PCRE_NEWLINE_CR
+         PCRE_NEWLINE_LF
+         PCRE_NEWLINE_CRLF
+
+       These  options  override the default newline definition that was chosen
+       when PCRE was built. Setting the first or the second specifies  that  a
+       newline  is  indicated  by a single character (CR or LF, respectively).
+       Setting both of them specifies that a newline is indicated by the  two-
+       character  CRLF sequence. For convenience, PCRE_NEWLINE_CRLF is defined
+       to contain both bits. The only time that a line break is relevant  when
+       compiling a pattern is if PCRE_EXTENDED is set, and an unescaped # out-
+       side a character class is encountered. This indicates  a  comment  that
+       lasts until after the next newline.
+
+       The newline option set at compile time becomes the default that is used
+       for pcre_exec() and pcre_dfa_exec(), but it can be overridden.
+
          PCRE_NO_AUTO_CAPTURE
 
        If this option is set, it disables the use of numbered capturing paren-
-       theses in the pattern. Any opening parenthesis that is not followed  by
-       ?  behaves as if it were followed by ?: but named parentheses can still
-       be used for capturing (and they acquire  numbers  in  the  usual  way).
+       theses  in the pattern. Any opening parenthesis that is not followed by
+       ? behaves as if it were followed by ?: but named parentheses can  still
+       be  used  for  capturing  (and  they acquire numbers in the usual way).
        There is no equivalent of this option in Perl.
 
          PCRE_UNGREEDY
 
-       This  option  inverts  the "greediness" of the quantifiers so that they
-       are not greedy by default, but become greedy if followed by "?". It  is
-       not  compatible  with Perl. It can also be set by a (?U) option setting
+       This option inverts the "greediness" of the quantifiers  so  that  they
+       are  not greedy by default, but become greedy if followed by "?". It is
+       not compatible with Perl. It can also be set by a (?U)  option  setting
        within the pattern.
 
          PCRE_UTF8
 
-       This option causes PCRE to regard both the pattern and the  subject  as
-       strings  of  UTF-8 characters instead of single-byte character strings.
-       However, it is available only when PCRE is built to include UTF-8  sup-
-       port.  If not, the use of this option provokes an error. Details of how
-       this option changes the behaviour of PCRE are given in the  section  on
+       This  option  causes PCRE to regard both the pattern and the subject as
+       strings of UTF-8 characters instead of single-byte  character  strings.
+       However,  it is available only when PCRE is built to include UTF-8 sup-
+       port. If not, the use of this option provokes an error. Details of  how
+       this  option  changes the behaviour of PCRE are given in the section on
        UTF-8 support in the main pcre page.
 
          PCRE_NO_UTF8_CHECK
 
        When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is
-       automatically checked. If an invalid UTF-8 sequence of bytes is  found,
-       pcre_compile()  returns an error. If you already know that your pattern
-       is valid, and you want to skip this check for performance reasons,  you
-       can  set  the  PCRE_NO_UTF8_CHECK option. When it is set, the effect of
+       automatically  checked. If an invalid UTF-8 sequence of bytes is found,
+       pcre_compile() returns an error. If you already know that your  pattern
+       is  valid, and you want to skip this check for performance reasons, you
+       can set the PCRE_NO_UTF8_CHECK option. When it is set,  the  effect  of
        passing an invalid UTF-8 string as a pattern is undefined. It may cause
-       your  program  to  crash.   Note that this option can also be passed to
-       pcre_exec() and pcre_dfa_exec(), to suppress the UTF-8 validity  check-
+       your program to crash.  Note that this option can  also  be  passed  to
+       pcre_exec()  and pcre_dfa_exec(), to suppress the UTF-8 validity check-
        ing of subject strings.
 
 
 COMPILATION ERROR CODES
 
-       The  following  table  lists  the  error  codes than may be returned by
-       pcre_compile2(), along with the error messages that may be returned  by
+       The following table lists the error  codes  than  may  be  returned  by
+       pcre_compile2(),  along with the error messages that may be returned by
        both compiling functions.
 
           0  no error
@@ -1067,7 +1147,7 @@ COMPILATION ERROR CODES
          23  internal error: code overflow
          24  unrecognized character after (?<
          25  lookbehind assertion is not fixed length
-         26  malformed number after (?(
+         26  malformed number or name after (?(
          27  conditional group contains more than two branches
          28  assertion expected after (?(
          29  (?R or (?digits must be followed by )
@@ -1084,11 +1164,15 @@ COMPILATION ERROR CODES
          40  recursive call could loop indefinitely
          41  unrecognized character after (?P
          42  syntax error after (?P
-         43  two named groups have the same name
+         43  two named subpatterns have the same name
          44  invalid UTF-8 string
          45  support for \P, \p, and \X has not been compiled
          46  malformed \P or \p sequence
          47  unknown property name after \P or \p
+         48  subpattern name is too long (maximum 32 characters)
+         49  too many named subpatterns (maximum 10,000)
+         50  repeated subpattern is too long
+         51  octal value is greater than \377 (not in UTF-8 mode)
 
 
 STUDYING A PATTERN
@@ -1096,32 +1180,32 @@ STUDYING A PATTERN
        pcre_extra *pcre_study(const pcre *code, int options
             const char **errptr);
 
-       If  a  compiled  pattern is going to be used several times, it is worth
+       If a compiled pattern is going to be used several times,  it  is  worth
        spending more time analyzing it in order to speed up the time taken for
-       matching.  The function pcre_study() takes a pointer to a compiled pat-
+       matching. The function pcre_study() takes a pointer to a compiled  pat-
        tern as its first argument. If studying the pattern produces additional
-       information  that  will  help speed up matching, pcre_study() returns a
-       pointer to a pcre_extra block, in which the study_data field points  to
+       information that will help speed up matching,  pcre_study()  returns  a
+       pointer  to a pcre_extra block, in which the study_data field points to
        the results of the study.
 
        The  returned  value  from  pcre_study()  can  be  passed  directly  to
-       pcre_exec(). However, a pcre_extra block  also  contains  other  fields
-       that  can  be  set  by the caller before the block is passed; these are
+       pcre_exec().  However,  a  pcre_extra  block also contains other fields
+       that can be set by the caller before the block  is  passed;  these  are
        described below in the section on matching a pattern.
 
-       If studying the pattern does not  produce  any  additional  information
+       If  studying  the  pattern  does not produce any additional information
        pcre_study() returns NULL. In that circumstance, if the calling program
-       wants to pass any of the other fields to pcre_exec(), it  must  set  up
+       wants  to  pass  any of the other fields to pcre_exec(), it must set up
        its own pcre_extra block.
 
-       The  second  argument of pcre_study() contains option bits. At present,
+       The second argument of pcre_study() contains option bits.  At  present,
        no options are defined, and this argument should always be zero.
 
-       The third argument for pcre_study() is a pointer for an error  message.
-       If  studying  succeeds  (even  if no data is returned), the variable it
-       points to is set to NULL. Otherwise it is set to  point  to  a  textual
+       The  third argument for pcre_study() is a pointer for an error message.
+       If studying succeeds (even if no data is  returned),  the  variable  it
+       points  to  is  set  to NULL. Otherwise it is set to point to a textual
        error message. This is a static string that is part of the library. You
-       must not try to free it. You should test the  error  pointer  for  NULL
+       must  not  try  to  free it. You should test the error pointer for NULL
        after calling pcre_study(), to be sure that it has run successfully.
 
        This is a typical call to pcre_study():
@@ -1133,52 +1217,52 @@ STUDYING A PATTERN
            &error);        /* set to NULL or points to a message */
 
        At present, studying a pattern is useful only for non-anchored patterns
-       that do not have a single fixed starting character. A bitmap of  possi-
+       that  do not have a single fixed starting character. A bitmap of possi-
        ble starting bytes is created.
 
 
 LOCALE SUPPORT
 
-       PCRE  handles  caseless matching, and determines whether characters are
-       letters digits, or whatever, by reference to a set of  tables,  indexed
-       by  character  value.  When running in UTF-8 mode, this applies only to
-       characters with codes less than 128. Higher-valued  codes  never  match
-       escapes  such  as  \w or \d, but can be tested with \p if PCRE is built
-       with Unicode character property support. The use of locales  with  Uni-
+       PCRE handles caseless matching, and determines whether  characters  are
+       letters  digits,  or whatever, by reference to a set of tables, indexed
+       by character value. When running in UTF-8 mode, this  applies  only  to
+       characters  with  codes  less than 128. Higher-valued codes never match
+       escapes such as \w or \d, but can be tested with \p if  PCRE  is  built
+       with  Unicode  character property support. The use of locales with Uni-
        code is discouraged.
 
-       An  internal set of tables is created in the default C locale when PCRE
-       is built. This is used when the final  argument  of  pcre_compile()  is
-       NULL,  and  is  sufficient for many applications. An alternative set of
-       tables can, however, be supplied. These may be created in  a  different
-       locale  from the default. As more and more applications change to using
+       An internal set of tables is created in the default C locale when  PCRE
+       is  built.  This  is  used when the final argument of pcre_compile() is
+       NULL, and is sufficient for many applications. An  alternative  set  of
+       tables  can,  however, be supplied. These may be created in a different
+       locale from the default. As more and more applications change to  using
        Unicode, the need for this locale support is expected to die away.
 
-       External tables are built by calling  the  pcre_maketables()  function,
-       which  has no arguments, in the relevant locale. The result can then be
-       passed to pcre_compile() or pcre_exec()  as  often  as  necessary.  For
-       example,  to  build  and use tables that are appropriate for the French
-       locale (where accented characters with  values  greater  than  128  are
+       External  tables  are  built by calling the pcre_maketables() function,
+       which has no arguments, in the relevant locale. The result can then  be
+       passed  to  pcre_compile()  or  pcre_exec()  as often as necessary. For
+       example, to build and use tables that are appropriate  for  the  French
+       locale  (where  accented  characters  with  values greater than 128 are
        treated as letters), the following code could be used:
 
          setlocale(LC_CTYPE, "fr_FR");
          tables = pcre_maketables();
          re = pcre_compile(..., tables);
 
-       When  pcre_maketables()  runs,  the  tables are built in memory that is
-       obtained via pcre_malloc. It is the caller's responsibility  to  ensure
-       that  the memory containing the tables remains available for as long as
+       When pcre_maketables() runs, the tables are built  in  memory  that  is
+       obtained  via  pcre_malloc. It is the caller's responsibility to ensure
+       that the memory containing the tables remains available for as long  as
        it is needed.
 
        The pointer that is passed to pcre_compile() is saved with the compiled
-       pattern,  and the same tables are used via this pointer by pcre_study()
+       pattern, and the same tables are used via this pointer by  pcre_study()
        and normally also by pcre_exec(). Thus, by default, for any single pat-
        tern, compilation, studying and matching all happen in the same locale,
        but different patterns can be compiled in different locales.
 
-       It is possible to pass a table pointer or NULL (indicating the  use  of
-       the  internal  tables)  to  pcre_exec(). Although not intended for this
-       purpose, this facility could be used to match a pattern in a  different
+       It  is  possible to pass a table pointer or NULL (indicating the use of
+       the internal tables) to pcre_exec(). Although  not  intended  for  this
+       purpose,  this facility could be used to match a pattern in a different
        locale from the one in which it was compiled. Passing table pointers at
        run time is discussed below in the section on matching a pattern.
 
@@ -1188,15 +1272,15 @@ INFORMATION ABOUT A PATTERN
        int pcre_fullinfo(const pcre *code, const pcre_extra *extra,
             int what, void *where);
 
-       The pcre_fullinfo() function returns information about a compiled  pat-
+       The  pcre_fullinfo() function returns information about a compiled pat-
        tern. It replaces the obsolete pcre_info() function, which is neverthe-
        less retained for backwards compability (and is documented below).
 
-       The first argument for pcre_fullinfo() is a  pointer  to  the  compiled
-       pattern.  The second argument is the result of pcre_study(), or NULL if
-       the pattern was not studied. The third argument specifies  which  piece
-       of  information  is required, and the fourth argument is a pointer to a
-       variable to receive the data. The yield of the  function  is  zero  for
+       The  first  argument  for  pcre_fullinfo() is a pointer to the compiled
+       pattern. The second argument is the result of pcre_study(), or NULL  if
+       the  pattern  was not studied. The third argument specifies which piece
+       of information is required, and the fourth argument is a pointer  to  a
+       variable  to  receive  the  data. The yield of the function is zero for
        success, or one of the following negative numbers:
 
          PCRE_ERROR_NULL       the argument code was NULL
@@ -1204,51 +1288,50 @@ INFORMATION ABOUT A PATTERN
          PCRE_ERROR_BADMAGIC   the "magic number" was not found
          PCRE_ERROR_BADOPTION  the value of what was invalid
 
-       The  "magic  number" is placed at the start of each compiled pattern as
-       an simple check against passing an arbitrary memory pointer. Here is  a
-       typical  call  of pcre_fullinfo(), to obtain the length of the compiled
+       The "magic number" is placed at the start of each compiled  pattern  as
+       an  simple check against passing an arbitrary memory pointer. Here is a
+       typical call of pcre_fullinfo(), to obtain the length of  the  compiled
        pattern:
 
          int rc;
-         unsigned long int length;
+         size_t length;
          rc = pcre_fullinfo(
            re,               /* result of pcre_compile() */
            pe,               /* result of pcre_study(), or NULL */
            PCRE_INFO_SIZE,   /* what is required */
            &length);         /* where to put the data */
 
-       The possible values for the third argument are defined in  pcre.h,  and
+       The  possible  values for the third argument are defined in pcre.h, and
        are as follows:
 
          PCRE_INFO_BACKREFMAX
 
-       Return  the  number  of  the highest back reference in the pattern. The
-       fourth argument should point to an int variable. Zero  is  returned  if
+       Return the number of the highest back reference  in  the  pattern.  The
+       fourth  argument  should  point to an int variable. Zero is returned if
        there are no back references.
 
          PCRE_INFO_CAPTURECOUNT
 
-       Return  the  number of capturing subpatterns in the pattern. The fourth
+       Return the number of capturing subpatterns in the pattern.  The  fourth
        argument should point to an int variable.
 
          PCRE_INFO_DEFAULT_TABLES
 
-       Return a pointer to the internal default character tables within  PCRE.
-       The  fourth  argument should point to an unsigned char * variable. This
+       Return  a pointer to the internal default character tables within PCRE.
+       The fourth argument should point to an unsigned char *  variable.  This
        information call is provided for internal use by the pcre_study() func-
-       tion.  External  callers  can  cause PCRE to use its internal tables by
+       tion. External callers can cause PCRE to use  its  internal  tables  by
        passing a NULL table pointer.
 
          PCRE_INFO_FIRSTBYTE
 
-       Return information about the first byte of any matched  string,  for  a
-       non-anchored    pattern.    (This    option    used    to   be   called
-       PCRE_INFO_FIRSTCHAR; the old name is  still  recognized  for  backwards
-       compatibility.)
+       Return  information  about  the first byte of any matched string, for a
+       non-anchored pattern. The fourth argument should point to an int  vari-
+       able.  (This option used to be called PCRE_INFO_FIRSTCHAR; the old name
+       is still recognized for backwards compatibility.)
 
-       If  there  is  a  fixed first byte, for example, from a pattern such as
-       (cat|cow|coyote), it is returned in the integer pointed  to  by  where.
-       Otherwise, if either
+       If there is a fixed first byte, for example, from  a  pattern  such  as
+       (cat|cow|coyote). Otherwise, if either
 
        (a)  the pattern was compiled with the PCRE_MULTILINE option, and every
        branch starts with "^", or
@@ -1284,13 +1367,13 @@ INFORMATION ABOUT A PATTERN
 
        PCRE  supports the use of named as well as numbered capturing parenthe-
        ses. The names are just an additional way of identifying the  parenthe-
-       ses,  which  still  acquire  numbers.  A  convenience  function  called
-       pcre_get_named_substring() is provided  for  extracting  an  individual
-       captured  substring  by  name.  It is also possible to extract the data
-       directly, by first converting the name to a number in order  to  access
-       the  correct  pointers in the output vector (described with pcre_exec()
-       below). To do the conversion, you need to use the  name-to-number  map,
-       which is described by these three values.
+       ses, which still acquire numbers. Several convenience functions such as
+       pcre_get_named_substring() are provided for  extracting  captured  sub-
+       strings  by  name. It is also possible to extract the data directly, by
+       first converting the name to a number in order to  access  the  correct
+       pointers in the output vector (described with pcre_exec() below). To do
+       the conversion, you need  to  use  the  name-to-number  map,  which  is
+       described by these three values.
 
        The map consists of a number of fixed-size entries. PCRE_INFO_NAMECOUNT
        gives the number of entries, and PCRE_INFO_NAMEENTRYSIZE gives the size
@@ -1300,8 +1383,10 @@ INFORMATION ABOUT A PATTERN
        first two bytes of each entry are the number of the capturing parenthe-
        sis,  most  significant byte first. The rest of the entry is the corre-
        sponding name, zero terminated. The names are  in  alphabetical  order.
-       For  example,  consider  the following pattern (assume PCRE_EXTENDED is
-       set, so white space - including newlines - is ignored):
+       When PCRE_DUPNAMES is set, duplicate names are in order of their paren-
+       theses numbers. For example, consider  the  following  pattern  (assume
+       PCRE_EXTENDED  is  set,  so  white  space  -  including  newlines  - is
+       ignored):
 
          (?P<date> (?P<year>(\d\d)?\d\d) -
          (?P<month>\d\d) - (?P<day>\d\d) )
@@ -1317,8 +1402,8 @@ INFORMATION ABOUT A PATTERN
          00 02 y  e  a  r  00 ??
 
        When  writing  code  to  extract  data from named subpatterns using the
-       name-to-number map, remember that the length of each entry is likely to
-       be different for each compiled pattern.
+       name-to-number map, remember that the length of the entries  is  likely
+       to be different for each compiled pattern.
 
          PCRE_INFO_OPTIONS
 
@@ -1517,16 +1602,26 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
    Option bits for pcre_exec()
 
        The unused bits of the options argument for pcre_exec() must  be  zero.
-       The   only  bits  that  may  be  set  are  PCRE_ANCHORED,  PCRE_NOTBOL,
-       PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NO_UTF8_CHECK and PCRE_PARTIAL.
+       The  only  bits  that  may  be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx,
+       PCRE_NOTBOL,   PCRE_NOTEOL,   PCRE_NOTEMPTY,   PCRE_NO_UTF8_CHECK   and
+       PCRE_PARTIAL.
 
          PCRE_ANCHORED
 
-       The PCRE_ANCHORED option limits pcre_exec() to matching  at  the  first
-       matching  position.  If  a  pattern was compiled with PCRE_ANCHORED, or
-       turned out to be anchored by virtue of its contents, it cannot be  made
+       The  PCRE_ANCHORED  option  limits pcre_exec() to matching at the first
+       matching position. If a pattern was  compiled  with  PCRE_ANCHORED,  or
+       turned  out to be anchored by virtue of its contents, it cannot be made
        unachored at matching time.
 
+         PCRE_NEWLINE_CR
+         PCRE_NEWLINE_LF
+         PCRE_NEWLINE_CRLF
+
+       These options override  the  newline  definition  that  was  chosen  or
+       defaulted  when the pattern was compiled. For details, see the descrip-
+       tion pcre_compile() above. During matching, the newline choice  affects
+       the behaviour of the dot, circumflex, and dollar metacharacters.
+
          PCRE_NOTBOL
 
        This option specifies that first character of the subject string is not
@@ -1662,41 +1757,50 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
        after  the  end  of  a  substring. The first pair, ovector[0] and ovec-
        tor[1], identify the portion of  the  subject  string  matched  by  the
        entire  pattern.  The next pair is used for the first capturing subpat-
-       tern, and so on. The value returned by pcre_exec()  is  the  number  of
-       pairs  that  have  been set. If there are no capturing subpatterns, the
-       return value from a successful match is 1,  indicating  that  just  the
-       first pair of offsets has been set.
-
-       Some  convenience  functions  are  provided for extracting the captured
-       substrings as separate strings. These are described  in  the  following
-       section.
-
-       It  is  possible  for  an capturing subpattern number n+1 to match some
-       part of the subject when subpattern n has not been  used  at  all.  For
-       example, if the string "abc" is matched against the pattern (a|(z))(bc)
-       subpatterns 1 and 3 are matched, but 2 is not. When this happens,  both
-       offset values corresponding to the unused subpattern are set to -1.
+       tern, and so on. The value returned by pcre_exec() is one more than the
+       highest numbered pair that has been set. For example, if two substrings
+       have been captured, the returned value is 3. If there are no  capturing
+       subpatterns,  the return value from a successful match is 1, indicating
+       that just the first pair of offsets has been set.
 
        If a capturing subpattern is matched repeatedly, it is the last portion
        of the string that it matched that is returned.
 
-       If the vector is too small to hold all the captured substring  offsets,
+       If  the vector is too small to hold all the captured substring offsets,
        it is used as far as possible (up to two-thirds of its length), and the
-       function returns a value of zero. In particular, if the substring  off-
+       function  returns a value of zero. In particular, if the substring off-
        sets are not of interest, pcre_exec() may be called with ovector passed
-       as NULL and ovecsize as zero. However, if  the  pattern  contains  back
-       references  and  the  ovector is not big enough to remember the related
-       substrings, PCRE has to get additional memory for use during  matching.
+       as  NULL  and  ovecsize  as zero. However, if the pattern contains back
+       references and the ovector is not big enough to  remember  the  related
+       substrings,  PCRE has to get additional memory for use during matching.
        Thus it is usually advisable to supply an ovector.
 
-       Note  that  pcre_info() can be used to find out how many capturing sub-
-       patterns there are in a compiled pattern. The smallest size for ovector
-       that  will  allow for n captured substrings, in addition to the offsets
-       of the substring matched by the whole pattern, is (n+1)*3.
+       The pcre_info() function can be used to find  out  how  many  capturing
+       subpatterns  there  are  in  a  compiled pattern. The smallest size for
+       ovector that will allow for n captured substrings, in addition  to  the
+       offsets of the substring matched by the whole pattern, is (n+1)*3.
+
+       It  is  possible for capturing subpattern number n+1 to match some part
+       of the subject when subpattern n has not been used at all. For example,
+       if  the  string  "abc"  is  matched against the pattern (a|(z))(bc) the
+       return from the function is 4, and subpatterns 1 and 3 are matched, but
+       2  is  not.  When  this happens, both values in the offset pairs corre-
+       sponding to unused subpatterns are set to -1.
+
+       Offset values that correspond to unused subpatterns at the end  of  the
+       expression  are  also  set  to  -1. For example, if the string "abc" is
+       matched against the pattern (abc)(x(yz)?)? subpatterns 2 and 3 are  not
+       matched.  The  return  from the function is 2, because the highest used
+       capturing subpattern number is 1. However, you can refer to the offsets
+       for  the  second  and third capturing subpatterns if you wish (assuming
+       the vector is large enough, of course).
 
-   Return values from pcre_exec()
+       Some convenience functions are provided  for  extracting  the  captured
+       substrings as separate strings. These are described below.
 
-       If pcre_exec() fails, it returns a negative number. The  following  are
+   Error return values from pcre_exec()
+
+       If  pcre_exec()  fails, it returns a negative number. The following are
        defined in the header file:
 
          PCRE_ERROR_NOMATCH        (-1)
@@ -1705,7 +1809,7 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
 
          PCRE_ERROR_NULL           (-2)
 
-       Either  code  or  subject  was  passed as NULL, or ovector was NULL and
+       Either code or subject was passed as NULL,  or  ovector  was  NULL  and
        ovecsize was not zero.
 
          PCRE_ERROR_BADOPTION      (-3)
@@ -1714,80 +1818,80 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
 
          PCRE_ERROR_BADMAGIC       (-4)
 
-       PCRE stores a 4-byte "magic number" at the start of the compiled  code,
+       PCRE  stores a 4-byte "magic number" at the start of the compiled code,
        to catch the case when it is passed a junk pointer and to detect when a
        pattern that was compiled in an environment of one endianness is run in
-       an  environment  with the other endianness. This is the error that PCRE
+       an environment with the other endianness. This is the error  that  PCRE
        gives when the magic number is not present.
 
          PCRE_ERROR_UNKNOWN_NODE   (-5)
 
        While running the pattern match, an unknown item was encountered in the
-       compiled  pattern.  This  error  could be caused by a bug in PCRE or by
+       compiled pattern. This error could be caused by a bug  in  PCRE  or  by
        overwriting of the compiled pattern.
 
          PCRE_ERROR_NOMEMORY       (-6)
 
-       If a pattern contains back references, but the ovector that  is  passed
+       If  a  pattern contains back references, but the ovector that is passed
        to pcre_exec() is not big enough to remember the referenced substrings,
-       PCRE gets a block of memory at the start of matching to  use  for  this
-       purpose.  If the call via pcre_malloc() fails, this error is given. The
+       PCRE  gets  a  block of memory at the start of matching to use for this
+       purpose. If the call via pcre_malloc() fails, this error is given.  The
        memory is automatically freed at the end of matching.
 
          PCRE_ERROR_NOSUBSTRING    (-7)
 
-       This error is used by the pcre_copy_substring(),  pcre_get_substring(),
+       This  error is used by the pcre_copy_substring(), pcre_get_substring(),
        and  pcre_get_substring_list()  functions  (see  below).  It  is  never
        returned by pcre_exec().
 
          PCRE_ERROR_MATCHLIMIT     (-8)
 
-       The backtracking limit, as specified by  the  match_limit  field  in  a
-       pcre_extra  structure  (or  defaulted) was reached. See the description
+       The  backtracking  limit,  as  specified  by the match_limit field in a
+       pcre_extra structure (or defaulted) was reached.  See  the  description
        above.
 
          PCRE_ERROR_RECURSIONLIMIT (-21)
 
        The internal recursion limit, as specified by the match_limit_recursion
-       field  in  a  pcre_extra  structure (or defaulted) was reached. See the
+       field in a pcre_extra structure (or defaulted)  was  reached.  See  the
        description above.
 
          PCRE_ERROR_CALLOUT        (-9)
 
        This error is never generated by pcre_exec() itself. It is provided for
-       use  by  callout functions that want to yield a distinctive error code.
+       use by callout functions that want to yield a distinctive  error  code.
        See the pcrecallout documentation for details.
 
          PCRE_ERROR_BADUTF8        (-10)
 
-       A string that contains an invalid UTF-8 byte sequence was passed  as  a
+       A  string  that contains an invalid UTF-8 byte sequence was passed as a
        subject.
 
          PCRE_ERROR_BADUTF8_OFFSET (-11)
 
        The UTF-8 byte sequence that was passed as a subject was valid, but the
-       value of startoffset did not point to the beginning of a UTF-8  charac-
+       value  of startoffset did not point to the beginning of a UTF-8 charac-
        ter.
 
          PCRE_ERROR_PARTIAL        (-12)
 
-       The  subject  string did not match, but it did match partially. See the
+       The subject string did not match, but it did match partially.  See  the
        pcrepartial documentation for details of partial matching.
 
          PCRE_ERROR_BADPARTIAL     (-13)
 
-       The PCRE_PARTIAL option was used with  a  compiled  pattern  containing
-       items  that are not supported for partial matching. See the pcrepartial
+       The  PCRE_PARTIAL  option  was  used with a compiled pattern containing
+       items that are not supported for partial matching. See the  pcrepartial
        documentation for details of partial matching.
 
          PCRE_ERROR_INTERNAL       (-14)
 
-       An unexpected internal error has occurred. This error could  be  caused
+       An  unexpected  internal error has occurred. This error could be caused
        by a bug in PCRE or by overwriting of the compiled pattern.
 
          PCRE_ERROR_BADCOUNT       (-15)
 
-       This  error is given if the value of the ovecsize argument is negative.
+       This error is given if the value of the ovecsize argument is  negative.
 
 
 EXTRACTING CAPTURED SUBSTRINGS BY NUMBER
@@ -1803,71 +1907,77 @@ EXTRACTING CAPTURED SUBSTRINGS BY NUMBER
        int pcre_get_substring_list(const char *subject,
             int *ovector, int stringcount, const char ***listptr);
 
-       Captured substrings can be  accessed  directly  by  using  the  offsets
-       returned  by  pcre_exec()  in  ovector.  For convenience, the functions
+       Captured  substrings  can  be  accessed  directly  by using the offsets
+       returned by pcre_exec() in  ovector.  For  convenience,  the  functions
        pcre_copy_substring(),    pcre_get_substring(),    and    pcre_get_sub-
-       string_list()  are  provided for extracting captured substrings as new,
-       separate, zero-terminated strings. These functions identify  substrings
-       by  number.  The  next section describes functions for extracting named
-       substrings. A substring  that  contains  a  binary  zero  is  correctly
-       extracted  and  has  a further zero added on the end, but the result is
-       not, of course, a C string.
-
-       The first three arguments are the same for all  three  of  these  func-
-       tions:  subject  is  the subject string that has just been successfully
+       string_list() are provided for extracting captured substrings  as  new,
+       separate,  zero-terminated strings. These functions identify substrings
+       by number. The next section describes functions  for  extracting  named
+       substrings.
+
+       A  substring that contains a binary zero is correctly extracted and has
+       a further zero added on the end, but the result is not, of course, a  C
+       string.   However,  you  can  process such a string by referring to the
+       length that is  returned  by  pcre_copy_substring()  and  pcre_get_sub-
+       string().  Unfortunately, the interface to pcre_get_substring_list() is
+       not adequate for handling strings containing binary zeros, because  the
+       end of the final string is not independently indicated.
+
+       The  first  three  arguments  are the same for all three of these func-
+       tions: subject is the subject string that has  just  been  successfully
        matched, ovector is a pointer to the vector of integer offsets that was
        passed to pcre_exec(), and stringcount is the number of substrings that
-       were captured by the match, including the substring  that  matched  the
+       were  captured  by  the match, including the substring that matched the
        entire regular expression. This is the value returned by pcre_exec() if
-       it is greater than zero. If pcre_exec() returned zero, indicating  that
-       it  ran out of space in ovector, the value passed as stringcount should
+       it  is greater than zero. If pcre_exec() returned zero, indicating that
+       it ran out of space in ovector, the value passed as stringcount  should
        be the number of elements in the vector divided by three.
 
-       The functions pcre_copy_substring() and pcre_get_substring() extract  a
-       single  substring,  whose  number  is given as stringnumber. A value of
-       zero extracts the substring that matched the  entire  pattern,  whereas
-       higher  values  extract  the  captured  substrings.  For pcre_copy_sub-
-       string(), the string is placed in buffer,  whose  length  is  given  by
-       buffersize,  while  for  pcre_get_substring()  a new block of memory is
-       obtained via pcre_malloc, and its address is  returned  via  stringptr.
-       The  yield  of  the function is the length of the string, not including
+       The  functions pcre_copy_substring() and pcre_get_substring() extract a
+       single substring, whose number is given as  stringnumber.  A  value  of
+       zero  extracts  the  substring that matched the entire pattern, whereas
+       higher values  extract  the  captured  substrings.  For  pcre_copy_sub-
+       string(),  the  string  is  placed  in buffer, whose length is given by
+       buffersize, while for pcre_get_substring() a new  block  of  memory  is
+       obtained  via  pcre_malloc,  and its address is returned via stringptr.
+       The yield of the function is the length of the  string,  not  including
        the terminating zero, or one of
 
          PCRE_ERROR_NOMEMORY       (-6)
 
-       The buffer was too small for pcre_copy_substring(), or the  attempt  to
+       The  buffer  was too small for pcre_copy_substring(), or the attempt to
        get memory failed for pcre_get_substring().
 
          PCRE_ERROR_NOSUBSTRING    (-7)
 
        There is no substring whose number is stringnumber.
 
-       The  pcre_get_substring_list()  function  extracts  all  available sub-
-       strings and builds a list of pointers to them. All this is  done  in  a
+       The pcre_get_substring_list()  function  extracts  all  available  sub-
+       strings  and  builds  a list of pointers to them. All this is done in a
        single block of memory that is obtained via pcre_malloc. The address of
-       the memory block is returned via listptr, which is also  the  start  of
-       the  list  of  string pointers. The end of the list is marked by a NULL
+       the  memory  block  is returned via listptr, which is also the start of
+       the list of string pointers. The end of the list is marked  by  a  NULL
        pointer. The yield of the function is zero if all went well, or
 
          PCRE_ERROR_NOMEMORY       (-6)
 
        if the attempt to get the memory block failed.
 
-       When any of these functions encounter a substring that is unset,  which
-       can  happen  when  capturing subpattern number n+1 matches some part of
-       the subject, but subpattern n has not been used at all, they return  an
+       When  any of these functions encounter a substring that is unset, which
+       can happen when capturing subpattern number n+1 matches  some  part  of
+       the  subject, but subpattern n has not been used at all, they return an
        empty string. This can be distinguished from a genuine zero-length sub-
-       string by inspecting the appropriate offset in ovector, which is  nega-
+       string  by inspecting the appropriate offset in ovector, which is nega-
        tive for unset substrings.
 
-       The  two convenience functions pcre_free_substring() and pcre_free_sub-
-       string_list() can be used to free the memory  returned  by  a  previous
+       The two convenience functions pcre_free_substring() and  pcre_free_sub-
+       string_list()  can  be  used  to free the memory returned by a previous
        call  of  pcre_get_substring()  or  pcre_get_substring_list(),  respec-
-       tively. They do nothing more than  call  the  function  pointed  to  by
-       pcre_free,  which  of course could be called directly from a C program.
-       However, PCRE is used in some situations where it is linked via a  spe-
-       cial  interface  to  another  programming  language  which  cannot  use
-       pcre_free directly; it is for these cases that the functions  are  pro-
+       tively.  They  do  nothing  more  than  call the function pointed to by
+       pcre_free, which of course could be called directly from a  C  program.
+       However,  PCRE is used in some situations where it is linked via a spe-
+       cial  interface  to  another  programming  language  that  cannot   use
+       pcre_free  directly;  it is for these cases that the functions are pro-
        vided.
 
 
@@ -1886,16 +1996,17 @@ EXTRACTING CAPTURED SUBSTRINGS BY NAME
             int stringcount, const char *stringname,
             const char **stringptr);
 
-       To  extract a substring by name, you first have to find associated num-
+       To extract a substring by name, you first have to find associated  num-
        ber.  For example, for this pattern
 
          (a+)b(?P<xxx>\d+)...
 
-       the number of the subpattern called "xxx" is 2. You can find the number
-       from the name by calling pcre_get_stringnumber(). The first argument is
-       the compiled pattern, and the second is the  name.  The  yield  of  the
-       function  is  the  subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if
-       there is no subpattern of that name.
+       the number of the subpattern called "xxx" is 2. If the name is known to
+       be unique (PCRE_DUPNAMES was not set), you can find the number from the
+       name by calling pcre_get_stringnumber(). The first argument is the com-
+       piled pattern, and the second is the name. The yield of the function is
+       the  subpattern  number,  or PCRE_ERROR_NOSUBSTRING (-7) if there is no
+       subpattern of that name.
 
        Given the number, you can extract the substring directly, or use one of
        the functions described in the previous section. For convenience, there
@@ -1917,21 +2028,50 @@ EXTRACTING CAPTURED SUBSTRINGS BY NAME
        ate.
 
 
+DUPLICATE SUBPATTERN NAMES
+
+       int pcre_get_stringtable_entries(const pcre *code,
+            const char *name, char **first, char **last);
+
+       When  a  pattern  is  compiled with the PCRE_DUPNAMES option, names for
+       subpatterns are not required to  be  unique.  Normally,  patterns  with
+       duplicate  names  are such that in any one match, only one of the named
+       subpatterns participates. An example is shown in the pcrepattern  docu-
+       mentation. When duplicates are present, pcre_copy_named_substring() and
+       pcre_get_named_substring() return the first substring corresponding  to
+       the  given  name  that  is  set.  If  none  are set, an empty string is
+       returned.  The pcre_get_stringnumber() function returns one of the num-
+       bers  that are associated with the name, but it is not defined which it
+       is.
+
+       If you want to get full details of all captured substrings for a  given
+       name,  you  must  use  the pcre_get_stringtable_entries() function. The
+       first argument is the compiled pattern, and the second is the name. The
+       third  and  fourth  are  pointers to variables which are updated by the
+       function. After it has run, they point to the first and last entries in
+       the  name-to-number  table  for  the  given  name.  The function itself
+       returns the length of each entry, or  PCRE_ERROR_NOSUBSTRING  if  there
+       are  none.  The  format  of the table is described above in the section
+       entitled Information about a pattern. Given all  the  relevant  entries
+       for the name, you can extract each of their numbers, and hence the cap-
+       tured data, if any.
+
+
 FINDING ALL POSSIBLE MATCHES
 
-       The  traditional  matching  function  uses a similar algorithm to Perl,
+       The traditional matching function uses a  similar  algorithm  to  Perl,
        which stops when it finds the first match, starting at a given point in
-       the  subject.  If you want to find all possible matches, or the longest
-       possible match, consider using the alternative matching  function  (see
-       below)  instead.  If you cannot use the alternative function, but still
-       need to find all possible matches, you can kludge it up by  making  use
+       the subject. If you want to find all possible matches, or  the  longest
+       possible  match,  consider using the alternative matching function (see
+       below) instead. If you cannot use the alternative function,  but  still
+       need  to  find all possible matches, you can kludge it up by making use
        of the callout facility, which is described in the pcrecallout documen-
        tation.
 
        What you have to do is to insert a callout right at the end of the pat-
-       tern.   When your callout function is called, extract and save the cur-
-       rent matched substring. Then return  1,  which  forces  pcre_exec()  to
-       backtrack  and  try other alternatives. Ultimately, when it runs out of
+       tern.  When your callout function is called, extract and save the  cur-
+       rent  matched  substring.  Then  return  1, which forces pcre_exec() to
+       backtrack and try other alternatives. Ultimately, when it runs  out  of
        matches, pcre_exec() will yield PCRE_ERROR_NOMATCH.
 
 
@@ -1942,25 +2082,25 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION
             int options, int *ovector, int ovecsize,
             int *workspace, int wscount);
 
-       The function pcre_dfa_exec()  is  called  to  match  a  subject  string
-       against  a compiled pattern, using a "DFA" matching algorithm. This has
-       different characteristics to the normal algorithm, and is not  compati-
+       The  function  pcre_dfa_exec()  is  called  to  match  a subject string
+       against a compiled pattern, using a "DFA" matching algorithm. This  has
+       different  characteristics to the normal algorithm, and is not compati-
        ble with Perl. Some of the features of PCRE patterns are not supported.
        Nevertheless, there are times when this kind of matching can be useful.
-       For  a  discussion of the two matching algorithms, see the pcrematching
+       For a discussion of the two matching algorithms, see  the  pcrematching
        documentation.
 
-       The arguments for the pcre_dfa_exec() function  are  the  same  as  for
+       The  arguments  for  the  pcre_dfa_exec()  function are the same as for
        pcre_exec(), plus two extras. The ovector argument is used in a differ-
-       ent way, and this is described below. The other  common  arguments  are
-       used  in  the  same way as for pcre_exec(), so their description is not
+       ent  way,  and  this is described below. The other common arguments are
+       used in the same way as for pcre_exec(), so their  description  is  not
        repeated here.
 
-       The two additional arguments provide workspace for  the  function.  The
-       workspace  vector  should  contain at least 20 elements. It is used for
+       The  two  additional  arguments provide workspace for the function. The
+       workspace vector should contain at least 20 elements. It  is  used  for
        keeping  track  of  multiple  paths  through  the  pattern  tree.  More
-       workspace  will  be  needed for patterns and subjects where there are a
-       lot of possible matches.
+       workspace will be needed for patterns and subjects where  there  are  a
+       lot of potential matches.
 
        Here is an example of a simple call to pcre_dfa_exec():
 
@@ -1981,47 +2121,47 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION
 
    Option bits for pcre_dfa_exec()
 
-       The unused bits of the options argument  for  pcre_dfa_exec()  must  be
-       zero.  The  only  bits  that may be set are PCRE_ANCHORED, PCRE_NOTBOL,
-       PCRE_NOTEOL,    PCRE_NOTEMPTY,    PCRE_NO_UTF8_CHECK,     PCRE_PARTIAL,
-       PCRE_DFA_SHORTEST,  and  PCRE_DFA_RESTART.  All  but  the last three of
-       these are the same as for pcre_exec(),  so  their  description  is  not
-       repeated here.
+       The  unused  bits  of  the options argument for pcre_dfa_exec() must be
+       zero. The only bits  that  may  be  set  are  PCRE_ANCHORED,  PCRE_NEW-
+       LINE_xxx,  PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NO_UTF8_CHECK,
+       PCRE_PARTIAL, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last
+       three of these are the same as for pcre_exec(), so their description is
+       not repeated here.
 
          PCRE_PARTIAL
 
-       This  has  the  same general effect as it does for pcre_exec(), but the
-       details  are  slightly  different.  When  PCRE_PARTIAL   is   set   for
-       pcre_dfa_exec(),  the  return code PCRE_ERROR_NOMATCH is converted into
-       PCRE_ERROR_PARTIAL if the end of the subject  is  reached,  there  have
+       This has the same general effect as it does for  pcre_exec(),  but  the
+       details   are   slightly   different.  When  PCRE_PARTIAL  is  set  for
+       pcre_dfa_exec(), the return code PCRE_ERROR_NOMATCH is  converted  into
+       PCRE_ERROR_PARTIAL  if  the  end  of the subject is reached, there have
        been no complete matches, but there is still at least one matching pos-
-       sibility. The portion of the string that provided the partial match  is
+       sibility.  The portion of the string that provided the partial match is
        set as the first matching string.
 
          PCRE_DFA_SHORTEST
 
-       Setting  the  PCRE_DFA_SHORTEST option causes the matching algorithm to
-       stop as soon as it has found one match. Because  of  the  way  the  DFA
+       Setting the PCRE_DFA_SHORTEST option causes the matching  algorithm  to
+       stop  as  soon  as  it  has found one match. Because of the way the DFA
        algorithm works, this is necessarily the shortest possible match at the
        first possible matching point in the subject string.
 
          PCRE_DFA_RESTART
 
-       When pcre_dfa_exec()  is  called  with  the  PCRE_PARTIAL  option,  and
-       returns  a  partial  match, it is possible to call it again, with addi-
-       tional subject characters, and have it continue with  the  same  match.
-       The  PCRE_DFA_RESTART  option requests this action; when it is set, the
-       workspace and wscount options must reference the same vector as  before
-       because  data  about  the  match so far is left in them after a partial
-       match. There is more discussion of this  facility  in  the  pcrepartial
+       When  pcre_dfa_exec()  is  called  with  the  PCRE_PARTIAL  option, and
+       returns a partial match, it is possible to call it  again,  with  addi-
+       tional  subject  characters,  and have it continue with the same match.
+       The PCRE_DFA_RESTART option requests this action; when it is  set,  the
+       workspace  and wscount options must reference the same vector as before
+       because data about the match so far is left in  them  after  a  partial
+       match.  There  is  more  discussion of this facility in the pcrepartial
        documentation.
 
    Successful returns from pcre_dfa_exec()
 
-       When  pcre_dfa_exec()  succeeds, it may have matched more than one sub-
+       When pcre_dfa_exec() succeeds, it may have matched more than  one  sub-
        string in the subject. Note, however, that all the matches from one run
-       of  the  function  start  at the same point in the subject. The shorter
-       matches are all initial substrings of the longer matches. For  example,
+       of the function start at the same point in  the  subject.  The  shorter
+       matches  are all initial substrings of the longer matches. For example,
        if the pattern
 
          <.*>
@@ -2036,58 +2176,58 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION
          <something> <something else>
          <something> <something else> <something further>
 
-       On  success,  the  yield of the function is a number greater than zero,
-       which is the number of matched substrings.  The  substrings  themselves
-       are  returned  in  ovector. Each string uses two elements; the first is
-       the offset to the start, and the second is the offset to the  end.  All
+       On success, the yield of the function is a number  greater  than  zero,
+       which  is  the  number of matched substrings. The substrings themselves
+       are returned in ovector. Each string uses two elements;  the  first  is
+       the  offset  to the start, and the second is the offset to the end. All
        the strings have the same start offset. (Space could have been saved by
-       giving this only once, but it was decided to retain some  compatibility
-       with  the  way pcre_exec() returns data, even though the meaning of the
+       giving  this only once, but it was decided to retain some compatibility
+       with the way pcre_exec() returns data, even though the meaning  of  the
        strings is different.)
 
        The strings are returned in reverse order of length; that is, the long-
-       est  matching  string is given first. If there were too many matches to
-       fit into ovector, the yield of the function is zero, and the vector  is
+       est matching string is given first. If there were too many  matches  to
+       fit  into ovector, the yield of the function is zero, and the vector is
        filled with the longest matches.
 
    Error returns from pcre_dfa_exec()
 
-       The  pcre_dfa_exec()  function returns a negative number when it fails.
-       Many of the errors are the same  as  for  pcre_exec(),  and  these  are
-       described  above.   There are in addition the following errors that are
+       The pcre_dfa_exec() function returns a negative number when  it  fails.
+       Many  of  the  errors  are  the  same as for pcre_exec(), and these are
+       described above.  There are in addition the following errors  that  are
        specific to pcre_dfa_exec():
 
          PCRE_ERROR_DFA_UITEM      (-16)
 
-       This return is given if pcre_dfa_exec() encounters an item in the  pat-
-       tern  that  it  does not support, for instance, the use of \C or a back
+       This  return is given if pcre_dfa_exec() encounters an item in the pat-
+       tern that it does not support, for instance, the use of \C  or  a  back
        reference.
 
          PCRE_ERROR_DFA_UCOND      (-17)
 
-       This return is given if pcre_dfa_exec() encounters a condition item  in
-       a  pattern  that  uses  a back reference for the condition. This is not
+       This  return is given if pcre_dfa_exec() encounters a condition item in
+       a pattern that uses a back reference for the  condition.  This  is  not
        supported.
 
          PCRE_ERROR_DFA_UMLIMIT    (-18)
 
-       This return is given if pcre_dfa_exec() is called with an  extra  block
+       This  return  is given if pcre_dfa_exec() is called with an extra block
        that contains a setting of the match_limit field. This is not supported
        (it is meaningless).
 
          PCRE_ERROR_DFA_WSSIZE     (-19)
 
-       This return is given if  pcre_dfa_exec()  runs  out  of  space  in  the
+       This  return  is  given  if  pcre_dfa_exec()  runs  out of space in the
        workspace vector.
 
          PCRE_ERROR_DFA_RECURSE    (-20)
 
-       When  a  recursive subpattern is processed, the matching function calls
-       itself recursively, using private vectors for  ovector  and  workspace.
-       This  error  is  given  if  the output vector is not large enough. This
+       When a recursive subpattern is processed, the matching  function  calls
+       itself  recursively,  using  private vectors for ovector and workspace.
+       This error is given if the output vector  is  not  large  enough.  This
        should be extremely rare, as a vector of size 1000 is used.
 
-Last updated: 18 January 2006
+Last updated: 08 June 2006
 Copyright (c) 1997-2006 University of Cambridge.
 ------------------------------------------------------------------------------
 
@@ -2334,25 +2474,26 @@ DIFFERENCES BETWEEN PCRE AND PERL
        meta-character matches only at the very end of the string.
 
        (c) If PCRE_EXTRA is set, a backslash followed by a letter with no spe-
-       cial meaning is faulted.
+       cial meaning  is  faulted.  Otherwise,  like  Perl,  the  backslash  is
+       ignored. (Perl can be made to issue a warning.)
 
-       (d) If PCRE_UNGREEDY is set, the greediness of the  repetition  quanti-
+       (d)  If  PCRE_UNGREEDY is set, the greediness of the repetition quanti-
        fiers is inverted, that is, by default they are not greedy, but if fol-
        lowed by a question mark they are.
 
        (e) PCRE_ANCHORED can be used at matching time to force a pattern to be
        tried only at the first matching position in the subject string.
 
-       (f)  The PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, and PCRE_NO_AUTO_CAP-
+       (f) The PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, and  PCRE_NO_AUTO_CAP-
        TURE options for pcre_exec() have no Perl equivalents.
 
-       (g) The (?R), (?number), and (?P>name) constructs allows for  recursive
-       pattern  matching  (Perl  can  do  this using the (?p{code}) construct,
+       (g)  The (?R), (?number), and (?P>name) constructs allows for recursive
+       pattern matching (Perl can do  this  using  the  (?p{code})  construct,
        which PCRE cannot support.)
 
-       (h) PCRE supports named capturing substrings, using the Python  syntax.
+       (h)  PCRE supports named capturing substrings, using the Python syntax.
 
-       (i)  PCRE  supports  the  possessive quantifier "++" syntax, taken from
+       (i) PCRE supports the possessive quantifier  "++"  syntax,  taken  from
        Sun's Java package.
 
        (j) The (R) condition, for testing recursion, is a PCRE extension.
@@ -2364,10 +2505,10 @@ DIFFERENCES BETWEEN PCRE AND PERL
        (m) Patterns compiled by PCRE can be saved and re-used at a later time,
        even on different hosts that have the other endianness.
 
-       (n)  The  alternative  matching function (pcre_dfa_exec()) matches in a
+       (n) The alternative matching function (pcre_dfa_exec())  matches  in  a
        different way and is not Perl-compatible.
 
-Last updated: 24 January 2006
+Last updated: 06 June 2006
 Copyright (c) 1997-2006 University of Cambridge.
 ------------------------------------------------------------------------------
 
@@ -2476,9 +2617,9 @@ BACKSLASH
 
        If  a  pattern is compiled with the PCRE_EXTENDED option, whitespace in
        the pattern (other than in a character class) and characters between  a
-       # outside a character class and the next newline character are ignored.
-       An escaping backslash can be used to include a whitespace or #  charac-
-       ter as part of the pattern.
+       # outside a character class and the next newline are ignored. An escap-
+       ing backslash can be used to include a whitespace  or  #  character  as
+       part of the pattern.
 
        If  you  want  to remove the special meaning from a sequence of charac-
        ters, you can do so by putting them between \Q and \E. This is  differ-
@@ -2535,26 +2676,27 @@ BACKSLASH
        two  syntaxes  for  \x. There is no difference in the way they are han-
        dled. For example, \xdc is exactly the same as \x{dc}.
 
-       After \0 up to two further octal digits are read.  In  both  cases,  if
-       there  are fewer than two digits, just those that are present are used.
-       Thus the sequence \0\x\07 specifies two binary zeros followed by a  BEL
-       character  (code  value  7).  Make sure you supply two digits after the
-       initial zero if the pattern character that follows is itself  an  octal
-       digit.
+       After \0 up to two further octal digits are read. If  there  are  fewer
+       than  two  digits,  just  those  that  are  present  are used. Thus the
+       sequence \0\x\07 specifies two binary zeros followed by a BEL character
+       (code  value 7). Make sure you supply two digits after the initial zero
+       if the pattern character that follows is itself an octal digit.
 
        The handling of a backslash followed by a digit other than 0 is compli-
        cated.  Outside a character class, PCRE reads it and any following dig-
-       its  as  a  decimal  number. If the number is less than 10, or if there
+       its as a decimal number. If the number is less than  10,  or  if  there
        have been at least that many previous capturing left parentheses in the
-       expression,  the  entire  sequence  is  taken  as  a  back reference. A
-       description of how this works is given later, following the  discussion
+       expression, the entire  sequence  is  taken  as  a  back  reference.  A
+       description  of how this works is given later, following the discussion
        of parenthesized subpatterns.
 
-       Inside  a  character  class, or if the decimal number is greater than 9
-       and there have not been that many capturing subpatterns, PCRE  re-reads
-       up  to three octal digits following the backslash, and generates a sin-
-       gle byte from the least significant 8 bits of the value. Any subsequent
-       digits stand for themselves.  For example:
+       Inside a character class, or if the decimal number is  greater  than  9
+       and  there have not been that many capturing subpatterns, PCRE re-reads
+       up to three octal digits following the backslash, ane uses them to gen-
+       erate  a data character. Any subsequent digits stand for themselves. In
+       non-UTF-8 mode, the value of a character specified  in  octal  must  be
+       less  than  \400.  In  UTF-8 mode, values up to \777 are permitted. For
+       example:
 
          \040   is another way of writing a space
          \40    is the same, provided there are fewer than 40
@@ -2571,15 +2713,14 @@ BACKSLASH
          \81    is either a back reference, or a binary zero
                    followed by the two characters "8" and "1"
 
-       Note  that  octal  values of 100 or greater must not be introduced by a
+       Note that octal values of 100 or greater must not be  introduced  by  a
        leading zero, because no more than three octal digits are ever read.
 
-       All the sequences that define a single byte value  or  a  single  UTF-8
-       character (in UTF-8 mode) can be used both inside and outside character
-       classes. In addition, inside a character  class,  the  sequence  \b  is
-       interpreted as the backspace character (hex 08), and the sequence \X is
-       interpreted as the character "X".  Outside  a  character  class,  these
-       sequences have different meanings (see below).
+       All the sequences that define a single character value can be used both
+       inside and outside character classes. In addition, inside  a  character
+       class,  the  sequence \b is interpreted as the backspace character (hex
+       08), and the sequence \X is interpreted as the character "X". Outside a
+       character class, these sequences have different meanings (see below).
 
    Generic character types
 
@@ -2604,7 +2745,9 @@ BACKSLASH
 
        For  compatibility  with Perl, \s does not match the VT character (code
        11).  This makes it different from the the POSIX "space" class. The  \s
-       characters are HT (9), LF (10), FF (12), CR (13), and space (32).
+       characters  are  HT (9), LF (10), FF (12), CR (13), and space (32). (If
+       "use locale;" is included in a Perl script, \s may match the VT charac-
+       ter. In PCRE, it never does.)
 
        A "word" character is an underscore or any character less than 256 that
        is a letter or digit. The definition of  letters  and  digits  is  con-
@@ -2719,7 +2862,7 @@ BACKSLASH
        classified as a modifier or "other".
 
        The  long  synonyms  for  these  properties that Perl supports (such as
-       \p{Letter}) are not supported by PCRE. Nor is is  permitted  to  prefix
+       \p{Letter}) are not supported by PCRE, nor is it  permitted  to  prefix
        any of these properties with "Is".
 
        No character that is in the Unicode table has the Cn (unassigned) prop-
@@ -2777,24 +2920,23 @@ BACKSLASH
        However, if the startoffset argument of pcre_exec() is non-zero,  indi-
        cating that matching is to start at a point other than the beginning of
        the subject, \A can never match. The difference between \Z  and  \z  is
-       that  \Z  matches  before  a  newline that is the last character of the
-       string as well as at the end of the string, whereas \z matches only  at
-       the end.
-
-       The  \G assertion is true only when the current matching position is at
-       the start point of the match, as specified by the startoffset  argument
-       of  pcre_exec().  It  differs  from \A when the value of startoffset is
-       non-zero. By calling pcre_exec() multiple times with appropriate  argu-
+       that \Z matches before a newline at the end of the string as well as at
+       the very end, whereas \z matches only at the end.
+
+       The \G assertion is true only when the current matching position is  at
+       the  start point of the match, as specified by the startoffset argument
+       of pcre_exec(). It differs from \A when the  value  of  startoffset  is
+       non-zero.  By calling pcre_exec() multiple times with appropriate argu-
        ments, you can mimic Perl's /g option, and it is in this kind of imple-
        mentation where \G can be useful.
 
-       Note, however, that PCRE's interpretation of \G, as the  start  of  the
+       Note,  however,  that  PCRE's interpretation of \G, as the start of the
        current match, is subtly different from Perl's, which defines it as the
-       end of the previous match. In Perl, these can  be  different  when  the
-       previously  matched  string was empty. Because PCRE does just one match
+       end  of  the  previous  match. In Perl, these can be different when the
+       previously matched string was empty. Because PCRE does just  one  match
        at a time, it cannot reproduce this behaviour.
 
-       If all the alternatives of a pattern begin with \G, the  expression  is
+       If  all  the alternatives of a pattern begin with \G, the expression is
        anchored to the starting match position, and the "anchored" flag is set
        in the compiled regular expression.
 
@@ -2802,68 +2944,81 @@ BACKSLASH
 CIRCUMFLEX AND DOLLAR
 
        Outside a character class, in the default matching mode, the circumflex
-       character  is  an  assertion  that is true only if the current matching
-       point is at the start of the subject string. If the  startoffset  argu-
-       ment  of  pcre_exec()  is  non-zero,  circumflex can never match if the
-       PCRE_MULTILINE option is unset. Inside a  character  class,  circumflex
+       character is an assertion that is true only  if  the  current  matching
+       point  is  at the start of the subject string. If the startoffset argu-
+       ment of pcre_exec() is non-zero, circumflex  can  never  match  if  the
+       PCRE_MULTILINE  option  is  unset. Inside a character class, circumflex
        has an entirely different meaning (see below).
 
-       Circumflex  need  not be the first character of the pattern if a number
-       of alternatives are involved, but it should be the first thing in  each
-       alternative  in  which  it appears if the pattern is ever to match that
-       branch. If all possible alternatives start with a circumflex, that  is,
-       if  the  pattern  is constrained to match only at the start of the sub-
-       ject, it is said to be an "anchored" pattern.  (There  are  also  other
+       Circumflex need not be the first character of the pattern if  a  number
+       of  alternatives are involved, but it should be the first thing in each
+       alternative in which it appears if the pattern is ever  to  match  that
+       branch.  If all possible alternatives start with a circumflex, that is,
+       if the pattern is constrained to match only at the start  of  the  sub-
+       ject,  it  is  said  to be an "anchored" pattern. (There are also other
        constructs that can cause a pattern to be anchored.)
 
-       A  dollar  character  is  an assertion that is true only if the current
-       matching point is at the end of  the  subject  string,  or  immediately
-       before a newline character that is the last character in the string (by
-       default). Dollar need not be the last character of  the  pattern  if  a
-       number  of alternatives are involved, but it should be the last item in
-       any branch in which it appears.  Dollar has no  special  meaning  in  a
-       character class.
+       A dollar character is an assertion that is true  only  if  the  current
+       matching  point  is  at  the  end of the subject string, or immediately
+       before a newline at the end of the string (by default). Dollar need not
+       be  the  last  character of the pattern if a number of alternatives are
+       involved, but it should be the last item in  any  branch  in  which  it
+       appears. Dollar has no special meaning in a character class.
 
        The  meaning  of  dollar  can be changed so that it matches only at the
        very end of the string, by setting the  PCRE_DOLLAR_ENDONLY  option  at
        compile time. This does not affect the \Z assertion.
 
        The meanings of the circumflex and dollar characters are changed if the
-       PCRE_MULTILINE option is set. When this is the case, they match immedi-
-       ately  after  and  immediately  before  an  internal newline character,
-       respectively, in addition to matching at the start and end of the  sub-
-       ject  string.  For  example,  the  pattern  /^abc$/ matches the subject
-       string "def\nabc" (where \n represents a newline character)  in  multi-
-       line mode, but not otherwise.  Consequently, patterns that are anchored
-       in single line mode because all branches start with ^ are not  anchored
-       in  multiline  mode,  and  a  match for circumflex is possible when the
-       startoffset  argument  of  pcre_exec()  is  non-zero.   The   PCRE_DOL-
-       LAR_ENDONLY option is ignored if PCRE_MULTILINE is set.
-
-       Note  that  the sequences \A, \Z, and \z can be used to match the start
-       and end of the subject in both modes, and if all branches of a  pattern
-       start  with  \A it is always anchored, whether PCRE_MULTILINE is set or
-       not.
+       PCRE_MULTILINE option is set. When  this  is  the  case,  a  circumflex
+       matches  immediately after internal newlines as well as at the start of
+       the subject string. It does not match after a  newline  that  ends  the
+       string.  A dollar matches before any newlines in the string, as well as
+       at the very end, when PCRE_MULTILINE is set. When newline is  specified
+       as  the  two-character  sequence CRLF, isolated CR and LF characters do
+       not indicate newlines.
+
+       For example, the pattern /^abc$/ matches the subject string  "def\nabc"
+       (where  \n  represents a newline) in multiline mode, but not otherwise.
+       Consequently, patterns that are anchored in single  line  mode  because
+       all  branches  start  with  ^ are not anchored in multiline mode, and a
+       match for circumflex is  possible  when  the  startoffset  argument  of
+       pcre_exec()  is  non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if
+       PCRE_MULTILINE is set.
+
+       Note that the sequences \A, \Z, and \z can be used to match  the  start
+       and  end of the subject in both modes, and if all branches of a pattern
+       start with \A it is always anchored, whether or not  PCRE_MULTILINE  is
+       set.
 
 
 FULL STOP (PERIOD, DOT)
 
        Outside a character class, a dot in the pattern matches any one charac-
-       ter  in  the  subject,  including a non-printing character, but not (by
-       default) newline.  In UTF-8 mode, a dot matches  any  UTF-8  character,
-       which might be more than one byte long, except (by default) newline. If
-       the PCRE_DOTALL option is set, dots match newlines as  well.  The  han-
-       dling  of dot is entirely independent of the handling of circumflex and
-       dollar, the only relationship being  that  they  both  involve  newline
-       characters. Dot has no special meaning in a character class.
+       ter in the subject string except (by default) a character  that  signi-
+       fies  the  end  of  a line. In UTF-8 mode, the matched character may be
+       more than one byte long. When a line ending  is  defined  as  a  single
+       character  (CR  or LF), dot never matches that character; when the two-
+       character sequence CRLF is used, dot does not match CR if it is immedi-
+       ately  followed by LF, but otherwise it matches all characters (includ-
+       ing isolated CRs and LFs).
+
+       The behaviour of dot with regard to newlines can  be  changed.  If  the
+       PCRE_DOTALL  option  is  set,  a dot matches any one character, without
+       exception. If newline is defined as the two-character sequence CRLF, it
+       takes two dots to match it.
+
+       The  handling of dot is entirely independent of the handling of circum-
+       flex and dollar, the only relationship being  that  they  both  involve
+       newlines. Dot has no special meaning in a character class.
 
 
 MATCHING A SINGLE BYTE
 
        Outside a character class, the escape sequence \C matches any one byte,
-       both in and out of UTF-8 mode. Unlike a dot, it can  match  a  newline.
-       The  feature  is provided in Perl in order to match individual bytes in
-       UTF-8 mode. Because it  breaks  up  UTF-8  characters  into  individual
+       both in and out of UTF-8 mode. Unlike a dot, it always matches  CR  and
+       LF.  The feature is provided in Perl in order to match individual bytes
+       in UTF-8 mode.  Because it breaks up UTF-8 characters  into  individual
        bytes,  what remains in the string may be a malformed UTF-8 string. For
        this reason, the \C escape sequence is best avoided.
 
@@ -2912,9 +3067,11 @@ SQUARE BRACKETS AND CHARACTER CLASSES
        PCRE  is  compiled  with Unicode property support as well as with UTF-8
        support.
 
-       The newline character is never treated in any special way in  character
-       classes,  whatever  the  setting  of  the PCRE_DOTALL or PCRE_MULTILINE
-       options is. A class such as [^a] will always match a newline.
+       Characters that might indicate  line  breaks  (CR  and  LF)  are  never
+       treated  in  any  special way when matching character classes, whatever
+       line-ending sequence is in use, and whatever setting of the PCRE_DOTALL
+       and PCRE_MULTILINE options is used. A class such as [^a] always matches
+       one of these characters.
 
        The minus (hyphen) character can be used to specify a range of  charac-
        ters  in  a  character  class.  For  example,  [d-m] matches any letter
@@ -3015,11 +3172,10 @@ VERTICAL BAR
 
        matches  either "gilbert" or "sullivan". Any number of alternatives may
        appear, and an empty  alternative  is  permitted  (matching  the  empty
-       string).   The  matching  process  tries each alternative in turn, from
-       left to right, and the first one that succeeds is used. If the alterna-
-       tives  are within a subpattern (defined below), "succeeds" means match-
-       ing the rest of the main pattern as well as the alternative in the sub-
-       pattern.
+       string). The matching process tries each alternative in turn, from left
+       to right, and the first one that succeeds is used. If the  alternatives
+       are  within a subpattern (defined below), "succeeds" means matching the
+       rest of the main pattern as well as the alternative in the  subpattern.
 
 
 INTERNAL OPTION SETTING
@@ -3065,12 +3221,9 @@ INTERNAL OPTION SETTING
        the effects of option settings happen at compile time. There  would  be
        some very weird behaviour otherwise.
 
-       The  PCRE-specific  options PCRE_UNGREEDY and PCRE_EXTRA can be changed
-       in the same way as the Perl-compatible options by using the  characters
-       U  and X respectively. The (?X) flag setting is special in that it must
-       always occur earlier in the pattern than any of the additional features
-       it  turns on, even when it is at top level. It is best to put it at the
-       start.
+       The  PCRE-specific options PCRE_DUPNAMES, PCRE_UNGREEDY, and PCRE_EXTRA
+       can be changed in the same way as the Perl-compatible options by  using
+       the characters J, U and X respectively.
 
 
 SUBPATTERNS
@@ -3082,18 +3235,18 @@ SUBPATTERNS
 
          cat(aract|erpillar|)
 
-       matches  one  of the words "cat", "cataract", or "caterpillar". Without
-       the parentheses, it would match "cataract",  "erpillar"  or  the  empty
+       matches one of the words "cat", "cataract", or  "caterpillar".  Without
+       the  parentheses,  it  would  match "cataract", "erpillar" or the empty
        string.
 
-       2.  It  sets  up  the  subpattern as a capturing subpattern. This means
-       that, when the whole pattern  matches,  that  portion  of  the  subject
+       2. It sets up the subpattern as  a  capturing  subpattern.  This  means
+       that,  when  the  whole  pattern  matches,  that portion of the subject
        string that matched the subpattern is passed back to the caller via the
-       ovector argument of pcre_exec(). Opening parentheses are  counted  from
-       left  to  right  (starting  from 1) to obtain numbers for the capturing
+       ovector  argument  of pcre_exec(). Opening parentheses are counted from
+       left to right (starting from 1) to obtain  numbers  for  the  capturing
        subpatterns.
 
-       For example, if the string "the red king" is matched against  the  pat-
+       For  example,  if the string "the red king" is matched against the pat-
        tern
 
          the ((red|white) (king|queen))
@@ -3101,50 +3254,75 @@ SUBPATTERNS
        the captured substrings are "red king", "red", and "king", and are num-
        bered 1, 2, and 3, respectively.
 
-       The fact that plain parentheses fulfil  two  functions  is  not  always
-       helpful.   There are often times when a grouping subpattern is required
-       without a capturing requirement. If an opening parenthesis is  followed
-       by  a question mark and a colon, the subpattern does not do any captur-
-       ing, and is not counted when computing the  number  of  any  subsequent
-       capturing  subpatterns. For example, if the string "the white queen" is
+       The  fact  that  plain  parentheses  fulfil two functions is not always
+       helpful.  There are often times when a grouping subpattern is  required
+       without  a capturing requirement. If an opening parenthesis is followed
+       by a question mark and a colon, the subpattern does not do any  captur-
+       ing,  and  is  not  counted when computing the number of any subsequent
+       capturing subpatterns. For example, if the string "the white queen"  is
        matched against the pattern
 
          the ((?:red|white) (king|queen))
 
        the captured substrings are "white queen" and "queen", and are numbered
-       1  and 2. The maximum number of capturing subpatterns is 65535, and the
-       maximum depth of nesting of all subpatterns, both  capturing  and  non-
+       1 and 2. The maximum number of capturing subpatterns is 65535, and  the
+       maximum  depth  of  nesting of all subpatterns, both capturing and non-
        capturing, is 200.
 
-       As  a  convenient shorthand, if any option settings are required at the
-       start of a non-capturing subpattern,  the  option  letters  may  appear
+       As a convenient shorthand, if any option settings are required  at  the
+       start  of  a  non-capturing  subpattern,  the option letters may appear
        between the "?" and the ":". Thus the two patterns
 
          (?i:saturday|sunday)
          (?:(?i)saturday|sunday)
 
        match exactly the same set of strings. Because alternative branches are
-       tried from left to right, and options are not reset until  the  end  of
-       the  subpattern is reached, an option setting in one branch does affect
-       subsequent branches, so the above patterns match "SUNDAY"  as  well  as
+       tried  from  left  to right, and options are not reset until the end of
+       the subpattern is reached, an option setting in one branch does  affect
+       subsequent  branches,  so  the above patterns match "SUNDAY" as well as
        "Saturday".
 
 
 NAMED SUBPATTERNS
 
-       Identifying  capturing  parentheses  by number is simple, but it can be
-       very hard to keep track of the numbers in complicated  regular  expres-
-       sions.  Furthermore,  if  an  expression  is  modified, the numbers may
-       change. To help with this difficulty, PCRE supports the naming of  sub-
-       patterns,  something  that  Perl  does  not  provide. The Python syntax
-       (?P<name>...) is used. Names consist  of  alphanumeric  characters  and
-       underscores, and must be unique within a pattern.
-
-       Named  capturing  parentheses  are  still  allocated numbers as well as
+       Identifying capturing parentheses by number is simple, but  it  can  be
+       very  hard  to keep track of the numbers in complicated regular expres-
+       sions. Furthermore, if an  expression  is  modified,  the  numbers  may
+       change.  To help with this difficulty, PCRE supports the naming of sub-
+       patterns, something that Perl  does  not  provide.  The  Python  syntax
+       (?P<name>...)  is  used. References to capturing parentheses from other
+       parts of the pattern, such as  backreferences,  recursion,  and  condi-
+       tions, can be made by name as well as by number.
+
+       Names  consist  of  up  to  32 alphanumeric characters and underscores.
+       Named capturing parentheses are still  allocated  numbers  as  well  as
        names. The PCRE API provides function calls for extracting the name-to-
-       number  translation table from a compiled pattern. There is also a con-
-       venience function for extracting a captured substring by name. For fur-
-       ther details see the pcreapi documentation.
+       number translation table from a compiled pattern. There is also a  con-
+       venience function for extracting a captured substring by name.
+
+       By  default, a name must be unique within a pattern, but it is possible
+       to relax this constraint by setting the PCRE_DUPNAMES option at compile
+       time.  This  can  be useful for patterns where only one instance of the
+       named parentheses can match. Suppose you want to match the  name  of  a
+       weekday,  either as a 3-letter abbreviation or as the full name, and in
+       both cases you want to extract the abbreviation. This pattern (ignoring
+       the line breaks) does the job:
+
+         (?P<DN>Mon|Fri|Sun)(?:day)?|
+         (?P<DN>Tue)(?:sday)?|
+         (?P<DN>Wed)(?:nesday)?|
+         (?P<DN>Thu)(?:rsday)?|
+         (?P<DN>Sat)(?:urday)?
+
+       There  are  five capturing substrings, but only one is ever set after a
+       match.  The convenience  function  for  extracting  the  data  by  name
+       returns  the  substring  for  the first, and in this example, the only,
+       subpattern of that name that matched.  This  saves  searching  to  find
+       which  numbered  subpattern  it  was. If you make a reference to a non-
+       unique named subpattern from elsewhere in the  pattern,  the  one  that
+       corresponds  to  the  lowest number is used. For further details of the
+       interfaces for handling named subpatterns, see the  pcreapi  documenta-
+       tion.
 
 
 REPETITION
@@ -3353,8 +3531,10 @@ ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
        meaning  or  processing  of  a possessive quantifier and the equivalent
        atomic group.
 
-       The possessive quantifier syntax is an extension to the Perl syntax. It
-       originates in Sun's Java package.
+       The possessive quantifier syntax is an extension to  the  Perl  syntax.
+       Jeffrey  Friedl originated the idea (and the name) in the first edition
+       of his book.  Mike McCloskey liked it, so implemented it when he  built
+       Sun's Java package, and PCRE copied it from there.
 
        When  a  pattern  contains an unlimited repeat inside a subpattern that
        can itself be repeated an unlimited number of  times,  the  use  of  an
@@ -3395,31 +3575,41 @@ BACK REFERENCES
        it  is  always  taken  as a back reference, and causes an error only if
        there are not that many capturing left parentheses in the  entire  pat-
        tern.  In  other words, the parentheses that are referenced need not be
-       to the left of the reference for numbers less than 10. See the  subsec-
-       tion  entitled  "Non-printing  characters" above for further details of
-       the handling of digits following a backslash.
+       to the left of the reference for numbers less than 10. A "forward  back
+       reference"  of  this  type can make sense when a repetition is involved
+       and the subpattern to the right has participated in an  earlier  itera-
+       tion.
+
+       It is not possible to have a numerical "forward back reference" to sub-
+       pattern whose number is 10 or more. However, a back  reference  to  any
+       subpattern  is  possible  using named parentheses (see below). See also
+       the subsection entitled "Non-printing  characters"  above  for  further
+       details of the handling of digits following a backslash.
 
-       A back reference matches whatever actually matched the  capturing  sub-
-       pattern  in  the  current subject string, rather than anything matching
+       A  back  reference matches whatever actually matched the capturing sub-
+       pattern in the current subject string, rather  than  anything  matching
        the subpattern itself (see "Subpatterns as subroutines" below for a way
        of doing that). So the pattern
 
          (sens|respons)e and \1ibility
 
-       matches  "sense and sensibility" and "response and responsibility", but
-       not "sense and responsibility". If caseful matching is in force at  the
-       time  of the back reference, the case of letters is relevant. For exam-
+       matches "sense and sensibility" and "response and responsibility",  but
+       not  "sense and responsibility". If caseful matching is in force at the
+       time of the back reference, the case of letters is relevant. For  exam-
        ple,
 
          ((?i)rah)\s+\1
 
-       matches "rah rah" and "RAH RAH", but not "RAH  rah",  even  though  the
+       matches  "rah  rah"  and  "RAH RAH", but not "RAH rah", even though the
        original capturing subpattern is matched caselessly.
 
-       Back  references  to named subpatterns use the Python syntax (?P=name).
+       Back references to named subpatterns use the Python  syntax  (?P=name).
        We could rewrite the above example as follows:
 
-         (?<p1>(?i)rah)\s+(?P=p1)
+         (?P<p1>(?i)rah)\s+(?P=p1)
+
+       A  subpattern  that  is  referenced  by  name may appear in the pattern
+       before or after the reference.
 
        There may be more than one back reference to the same subpattern. If  a
        subpattern  has  not actually been used in a particular match, any back
@@ -3508,8 +3698,8 @@ ASSERTIONS
        does  find  an  occurrence  of "bar" that is not preceded by "foo". The
        contents of a lookbehind assertion are restricted  such  that  all  the
        strings it matches must have a fixed length. However, if there are sev-
-       eral alternatives, they do not all have to have the same fixed  length.
-       Thus
+       eral top-level alternatives, they do not all  have  to  have  the  same
+       fixed length. Thus
 
          (?<=bullock|donkey)
 
@@ -3622,12 +3812,18 @@ CONDITIONAL SUBPATTERNS
        tives in the subpattern, a compile-time error occurs.
 
        There are three kinds of condition. If the text between the parentheses
-       consists of a sequence of digits, the condition  is  satisfied  if  the
-       capturing  subpattern of that number has previously matched. The number
-       must be greater than zero. Consider the following pattern,  which  con-
-       tains  non-significant white space to make it more readable (assume the
-       PCRE_EXTENDED option) and to divide it into three  parts  for  ease  of
-       discussion:
+       consists of a sequence of digits, or a sequence of alphanumeric charac-
+       ters  and underscores, the condition is satisfied if the capturing sub-
+       pattern of that number or name has previously matched. There is a  pos-
+       sible  ambiguity here, because subpattern names may consist entirely of
+       digits. PCRE looks first for a named subpattern; if it cannot find  one
+       and  the text consists entirely of digits, it looks for a subpattern of
+       that number, which must be greater than zero.  Using  subpattern  names
+       that consist entirely of digits is not recommended.
+
+       Consider  the  following  pattern, which contains non-significant white
+       space to make it more readable (assume the PCRE_EXTENDED option) and to
+       divide it into three parts for ease of discussion:
 
          ( \( )?    [^()]+    (?(1) \) )
 
@@ -3640,12 +3836,16 @@ CONDITIONAL SUBPATTERNS
        tern  is  executed  and  a  closing parenthesis is required. Otherwise,
        since no-pattern is not present, the  subpattern  matches  nothing.  In
        other  words,  this  pattern  matches  a  sequence  of non-parentheses,
-       optionally enclosed in parentheses.
+       optionally enclosed in parentheses. Rewriting it to use a named subpat-
+       tern gives this:
 
-       If the condition is the string (R), it is satisfied if a recursive call
-       to  the pattern or subpattern has been made. At "top level", the condi-
-       tion is false.  This  is  a  PCRE  extension.  Recursive  patterns  are
-       described in the next section.
+         (?P<OPEN> \( )?    [^()]+    (?(OPEN) \) )
+
+       If the condition is the string (R), and there is no subpattern with the
+       name R, the condition is satisfied if a recursive call to  the  pattern
+       or  subpattern  has  been made. At "top level", the condition is false.
+       This is a PCRE extension.  Recursive patterns are described in the next
+       section.
 
        If  the  condition  is  not  a sequence of digits or (R), it must be an
        assertion.  This may be a positive or negative lookahead or  lookbehind
@@ -3672,8 +3872,8 @@ COMMENTS
        at all.
 
        If  the PCRE_EXTENDED option is set, an unescaped # character outside a
-       character class introduces a comment that continues up to the next new-
-       line character in the pattern.
+       character class introduces a  comment  that  continues  to  immediately
+       after the next newline in the pattern.
 
 
 RECURSIVE PATTERNS
@@ -3796,50 +3996,51 @@ SUBPATTERNS AS SUBROUTINES
          (sens|respons)e and (?1)ibility
 
        is  used, it does match "sense and responsibility" as well as the other
-       two strings. Such references must, however, follow  the  subpattern  to
-       which they refer.
+       two strings. Such references, if given  numerically,  must  follow  the
+       subpattern  to which they refer. However, named references can refer to
+       later subpatterns.
 
        Like recursive subpatterns, a "subroutine" call is always treated as an
-       atomic group. That is, once it has matched some of the subject  string,
-       it  is  never  re-entered, even if it contains untried alternatives and
+       atomic  group. That is, once it has matched some of the subject string,
+       it is never re-entered, even if it contains  untried  alternatives  and
        there is a subsequent matching failure.
 
 
 CALLOUTS
 
        Perl has a feature whereby using the sequence (?{...}) causes arbitrary
-       Perl  code to be obeyed in the middle of matching a regular expression.
+       Perl code to be obeyed in the middle of matching a regular  expression.
        This makes it possible, amongst other things, to extract different sub-
        strings that match the same pair of parentheses when there is a repeti-
        tion.
 
        PCRE provides a similar feature, but of course it cannot obey arbitrary
        Perl code. The feature is called "callout". The caller of PCRE provides
-       an external function by putting its entry point in the global  variable
-       pcre_callout.   By default, this variable contains NULL, which disables
+       an  external function by putting its entry point in the global variable
+       pcre_callout.  By default, this variable contains NULL, which  disables
        all calling out.
 
-       Within a regular expression, (?C) indicates the  points  at  which  the
-       external  function  is  to be called. If you want to identify different
-       callout points, you can put a number less than 256 after the letter  C.
-       The  default  value is zero.  For example, this pattern has two callout
+       Within  a  regular  expression,  (?C) indicates the points at which the
+       external function is to be called. If you want  to  identify  different
+       callout  points, you can put a number less than 256 after the letter C.
+       The default value is zero.  For example, this pattern has  two  callout
        points:
 
          (?C1)abc(?C2)def
 
        If the PCRE_AUTO_CALLOUT flag is passed to pcre_compile(), callouts are
-       automatically  installed  before each item in the pattern. They are all
+       automatically installed before each item in the pattern. They  are  all
        numbered 255.
 
        During matching, when PCRE reaches a callout point (and pcre_callout is
-       set),  the  external function is called. It is provided with the number
-       of the callout, the position in the pattern, and, optionally, one  item
-       of  data  originally supplied by the caller of pcre_exec(). The callout
-       function may cause matching to proceed, to backtrack, or to fail  alto-
+       set), the external function is called. It is provided with  the  number
+       of  the callout, the position in the pattern, and, optionally, one item
+       of data originally supplied by the caller of pcre_exec().  The  callout
+       function  may cause matching to proceed, to backtrack, or to fail alto-
        gether. A complete description of the interface to the callout function
        is given in the pcrecallout documentation.
 
-Last updated: 24 January 2006
+Last updated: 06 June 2006
 Copyright (c) 1997-2006 University of Cambridge.
 ------------------------------------------------------------------------------
 
@@ -4847,3 +5048,106 @@ PCRE SAMPLE PROGRAM
 Last updated: 09 September 2004
 Copyright (c) 1997-2004 University of Cambridge.
 ------------------------------------------------------------------------------
+PCRESTACK(3)                                                      PCRESTACK(3)
+
+
+NAME
+       PCRE - Perl-compatible regular expressions
+
+
+PCRE DISCUSSION OF STACK USAGE
+
+       When  you call pcre_exec(), it makes use of an internal function called
+       match(). This calls itself recursively at branch points in the pattern,
+       in  order to remember the state of the match so that it can back up and
+       try a different alternative if the first one fails.  As  matching  pro-
+       ceeds  deeper  and deeper into the tree of possibilities, the recursion
+       depth increases.
+
+       Not all calls of match() increase the recursion depth; for an item such
+       as  a* it may be called several times at the same level, after matching
+       different numbers of a's. Furthermore, in a number of cases  where  the
+       result  of  the  recursive call would immediately be passed back as the
+       result of the current call (a "tail recursion"), the function  is  just
+       restarted instead.
+
+       The pcre_dfa_exec() function operates in an entirely different way, and
+       hardly uses recursion at all. The limit on its complexity is the amount
+       of  workspace  it  is  given.  The comments that follow do NOT apply to
+       pcre_dfa_exec(); they are relevant only for pcre_exec().
+
+       You can set limits on the number of times that match() is called,  both
+       in  total  and  recursively. If the limit is exceeded, an error occurs.
+       For details, see the section on  extra  data  for  pcre_exec()  in  the
+       pcreapi documentation.
+
+       Each  time  that match() is actually called recursively, it uses memory
+       from the process stack. For certain kinds of  pattern  and  data,  very
+       large  amounts of stack may be needed, despite the recognition of "tail
+       recursion".  You can often reduce the amount of recursion,  and  there-
+       fore  the  amount of stack used, by modifying the pattern that is being
+       matched. Consider, for example, this pattern:
+
+         ([^<]|<(?!inet))+
+
+       It matches from wherever it starts until it encounters "<inet"  or  the
+       end  of  the  data,  and is the kind of pattern that might be used when
+       processing an XML file. Each iteration of the outer parentheses matches
+       either  one  character that is not "<" or a "<" that is not followed by
+       "inet". However, each time a  parenthesis  is  processed,  a  recursion
+       occurs, so this formulation uses a stack frame for each matched charac-
+       ter. For a long string, a lot of stack is required. Consider  now  this
+       rewritten pattern, which matches exactly the same strings:
+
+         ([^<]++|<(?!inet))
+
+       This  uses very much less stack, because runs of characters that do not
+       contain "<" are "swallowed" in one item inside the parentheses.  Recur-
+       sion  happens  only when a "<" character that is not followed by "inet"
+       is encountered (and we assume this is relatively  rare).  A  possessive
+       quantifier  is  used  to stop any backtracking into the runs of non-"<"
+       characters, but that is not related to stack usage.
+
+       In environments where stack memory is constrained, you  might  want  to
+       compile  PCRE to use heap memory instead of stack for remembering back-
+       up points. This makes it run a lot more slowly, however. Details of how
+       to do this are given in the pcrebuild documentation.
+
+       In Unix-like environments, there is not often a problem with the stack,
+       though the default limit on stack size varies from  system  to  system.
+       Values  from 8Mb to 64Mb are common. You can find your default limit by
+       running the command:
+
+         ulimit -s
+
+       The effect of running out of stack is often SIGSEGV,  though  sometimes
+       an error message is given. You can normally increase the limit on stack
+       size by code such as this:
+
+         struct rlimit rlim;
+         getrlimit(RLIMIT_STACK, &rlim);
+         rlim.rlim_cur = 100*1024*1024;
+         setrlimit(RLIMIT_STACK, &rlim);
+
+       This reads the current limits (soft and hard) using  getrlimit(),  then
+       attempts  to  increase  the  soft limit to 100Mb using setrlimit(). You
+       must do this before calling pcre_exec().
+
+       PCRE has an internal counter that can be used to  limit  the  depth  of
+       recursion,  and  thus cause pcre_exec() to give an error code before it
+       runs out of stack. By default, the limit is very  large,  and  unlikely
+       ever  to operate. It can be changed when PCRE is built, and it can also
+       be set when pcre_exec() is called. For details of these interfaces, see
+       the pcrebuild and pcreapi documentation.
+
+       As a very rough rule of thumb, you should reckon on about 500 bytes per
+       recursion. Thus, if you want to limit your  stack  usage  to  8Mb,  you
+       should  set  the  limit at 16000 recursions. A 64Mb stack, on the other
+       hand, can support around 128000 recursions. The pcretest  test  program
+       has  a command line option (-S) that can be used to increase its stack.
+
+Last updated: 29 June 2006
+Copyright (c) 1997-2006 University of Cambridge.
+------------------------------------------------------------------------------
+
+
index e16cc7096cb3397f2b9056f41122e66b19fc3103..b4a19d2fa15901f6f04abe6f1a20a2fbaa686d85 100644 (file)
@@ -55,9 +55,9 @@ cannot run ./configure. As it now stands, this file need not be edited in that
 circumstance. */
 
 #define PCRE_MAJOR          6
-#define PCRE_MINOR          6
+#define PCRE_MINOR          7
 #define PCRE_PRERELEASE
-#define PCRE_DATE           06-Feb-2006
+#define PCRE_DATE           04-Jul-2006
 
 /* Win32 uses DLL by default; it needs special stuff for exported functions
 when building PCRE. */
@@ -116,6 +116,10 @@ extern "C" {
 #define PCRE_DFA_SHORTEST       0x00010000
 #define PCRE_DFA_RESTART        0x00020000
 #define PCRE_FIRSTLINE          0x00040000
+#define PCRE_DUPNAMES           0x00080000
+#define PCRE_NEWLINE_CR         0x00100000
+#define PCRE_NEWLINE_LF         0x00200000
+#define PCRE_NEWLINE_CRLF       0x00300000
 
 /* Exec-time and get/set-time error codes */
 
@@ -269,6 +273,8 @@ PCRE_DATA_SCOPE int  pcre_fullinfo(const pcre *, const pcre_extra *, int,
 PCRE_DATA_SCOPE int  pcre_get_named_substring(const pcre *, const char *,
                   int *, int, const char *, const char **);
 PCRE_DATA_SCOPE int  pcre_get_stringnumber(const pcre *, const char *);
+PCRE_DATA_SCOPE int  pcre_get_stringtable_entries(const pcre *, const char *,
+                  char **, char **);
 PCRE_DATA_SCOPE int  pcre_get_substring(const char *, int *, int, int,
                   const char **);
 PCRE_DATA_SCOPE int  pcre_get_substring_list(const char *, int *, int,
index 0bbc7f5ba18da7b4246157e4b9a27ef4abe05069..4ea73d9d3056c33a8d6906a3738b6070fc1e8bfa 100644 (file)
@@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
 supporting internal functions that are not used by other modules. */
 
 
+#define NLBLOCK cd            /* The block containing newline information */
 #include "pcre_internal.h"
 
 
@@ -190,7 +191,7 @@ static const char *error_texts[] = {
   "unrecognized character after (?<",
   /* 25 */
   "lookbehind assertion is not fixed length",
-  "malformed number after (?(",
+  "malformed number or name after (?(",
   "conditional group contains more than two branches",
   "assertion expected after (?(",
   "(?R or (?digits must be followed by )",
@@ -210,12 +211,17 @@ static const char *error_texts[] = {
   "recursive call could loop indefinitely",
   "unrecognized character after (?P",
   "syntax error after (?P",
-  "two named groups have the same name",
+  "two named subpatterns have the same name",
   "invalid UTF-8 string",
   /* 45 */
   "support for \\P, \\p, and \\X has not been compiled",
   "malformed \\P or \\p sequence",
-  "unknown property name after \\P or \\p"
+  "unknown property name after \\P or \\p",
+  "subpattern name is too long (maximum 32 characters)",
+  "too many named subpatterns (maximum 10,000)",
+  /* 50 */
+  "repeated subpattern is too long",
+  "octal value is greater than \\377 (not in UTF-8 mode)"
 };
 
 
@@ -460,13 +466,16 @@ else
       }
 
     /* \0 always starts an octal number, but we may drop through to here with a
-    larger first octal digit. */
+    larger first octal digit. The original code used just to take the least
+    significant 8 bits of octal numbers (I think this is what early Perls used
+    to do). Nowadays we allow for larger numbers in UTF-8 mode, but no more
+    than 3 octal digits. */
 
     case '0':
     c -= '0';
     while(i++ < 2 && ptr[1] >= '0' && ptr[1] <= '7')
         c = c * 8 + *(++ptr) - '0';
-    c &= 255;     /* Take least significant 8 bits */
+    if (!utf8 && c > 255) *errorcodeptr = ERR51;
     break;
 
     /* \x is complicated. \x{ddd} is a character number which can be greater
@@ -762,6 +771,48 @@ return p;
 
 
 
+/*************************************************
+*     Find forward referenced named subpattern   *
+*************************************************/
+
+/* This function scans along a pattern looking for capturing subpatterns, and
+counting them. If it finds a named pattern that matches the name it is given,
+it returns its number. This is used for forward references to named
+subpatterns. We know that if (?P< is encountered, the name will be terminated
+by '>' because that is checked in the first pass.
+
+Arguments:
+  pointer      current position in the pattern
+  count        current count of capturing parens
+  name         name to seek
+  namelen      name length
+
+Returns:       the number of the named subpattern, or -1 if not found
+*/
+
+static int
+find_named_parens(const uschar *ptr, int count, const uschar *name, int namelen)
+{
+const uschar *thisname;
+for (; *ptr != 0; ptr++)
+  {
+  if (*ptr == '\\' && ptr[1] != 0) { ptr++; continue; }
+  if (*ptr != '(') continue;
+  if (ptr[1] != '?') { count++; continue; }
+  if (ptr[2] == '(') { ptr += 2; continue; }
+  if (ptr[2] != 'P' || ptr[3] != '<') continue;
+  count++;
+  ptr += 4;
+  thisname = ptr;
+  while (*ptr != '>') ptr++;
+  if (namelen == ptr - thisname && strncmp(name, thisname, namelen) == 0)
+    return count;
+  }
+return -1;
+}
+
+
+
 /*************************************************
 *      Find first significant op code            *
 *************************************************/
@@ -917,6 +968,7 @@ for (;;)
 
     case OP_CHAR:
     case OP_CHARNC:
+    case OP_NOT:
     branchlength++;
     cc += 2;
 #ifdef SUPPORT_UTF8
@@ -1031,14 +1083,19 @@ Returns:      pointer to the opcode for the bracket, or NULL if not found
 static const uschar *
 find_bracket(const uschar *code, BOOL utf8, int number)
 {
-#ifndef SUPPORT_UTF8
-utf8 = utf8;               /* Stop pedantic compilers complaining */
-#endif
-
 for (;;)
   {
   register int c = *code;
   if (c == OP_END) return NULL;
+
+  /* XCLASS is used for classes that cannot be represented just by a bit
+  map. This includes negated single high-valued characters. The length in
+  the table is zero; the actual length is stored in the compiled code. */
+
+  if (c == OP_XCLASS) code += GET(code, 1);
+
+  /* Handle bracketed group */
+
   else if (c > OP_BRA)
     {
     int n = c - OP_BRA;
@@ -1046,17 +1103,16 @@ for (;;)
     if (n == number) return (uschar *)code;
     code += _pcre_OP_lengths[OP_BRA];
     }
+
+  /* Otherwise, we get the item's length from the table. In UTF-8 mode, opcodes
+  that are followed by a character may be followed by a multi-byte character.
+  The length in the table is a minimum, so we have to scan along to skip the
+  extra bytes. All opcodes are less than 128, so we can use relatively
+  efficient code. */
+
   else
     {
     code += _pcre_OP_lengths[c];
-
-#ifdef SUPPORT_UTF8
-
-    /* In UTF-8 mode, opcodes that are followed by a character may be followed
-    by a multi-byte character. The length in the table is a minimum, so we have
-    to scan along to skip the extra bytes. All opcodes are less than 128, so we
-    can use relatively efficient code. */
-
     if (utf8) switch(c)
       {
       case OP_CHAR:
@@ -1072,16 +1128,7 @@ for (;;)
       case OP_MINQUERY:
       while ((*code & 0xc0) == 0x80) code++;
       break;
-
-      /* XCLASS is used for classes that cannot be represented just by a bit
-      map. This includes negated single high-valued characters. The length in
-      the table is zero; the actual length is stored in the compiled code. */
-
-      case OP_XCLASS:
-      code += GET(code, 1) + 1;
-      break;
       }
-#endif
     }
   }
 }
@@ -1105,30 +1152,34 @@ Returns:      pointer to the opcode for OP_RECURSE, or NULL if not found
 static const uschar *
 find_recurse(const uschar *code, BOOL utf8)
 {
-#ifndef SUPPORT_UTF8
-utf8 = utf8;               /* Stop pedantic compilers complaining */
-#endif
-
 for (;;)
   {
   register int c = *code;
   if (c == OP_END) return NULL;
-  else if (c == OP_RECURSE) return code;
+  if (c == OP_RECURSE) return code;
+
+  /* XCLASS is used for classes that cannot be represented just by a bit
+  map. This includes negated single high-valued characters. The length in
+  the table is zero; the actual length is stored in the compiled code. */
+
+  if (c == OP_XCLASS) code += GET(code, 1);
+
+  /* All bracketed groups have the same length. */
+
   else if (c > OP_BRA)
     {
     code += _pcre_OP_lengths[OP_BRA];
     }
+
+  /* Otherwise, we get the item's length from the table. In UTF-8 mode, opcodes
+  that are followed by a character may be followed by a multi-byte character.
+  The length in the table is a minimum, so we have to scan along to skip the
+  extra bytes. All opcodes are less than 128, so we can use relatively
+  efficient code. */
+
   else
     {
     code += _pcre_OP_lengths[c];
-
-#ifdef SUPPORT_UTF8
-
-    /* In UTF-8 mode, opcodes that are followed by a character may be followed
-    by a multi-byte character. The length in the table is a minimum, so we have
-    to scan along to skip the extra bytes. All opcodes are less than 128, so we
-    can use relatively efficient code. */
-
     if (utf8) switch(c)
       {
       case OP_CHAR:
@@ -1144,16 +1195,7 @@ for (;;)
       case OP_MINQUERY:
       while ((*code & 0xc0) == 0x80) code++;
       break;
-
-      /* XCLASS is used for classes that cannot be represented just by a bit
-      map. This includes negated single high-valued characters. The length in
-      the table is zero; the actual length is stored in the compiled code. */
-
-      case OP_XCLASS:
-      code += GET(code, 1) + 1;
-      break;
       }
-#endif
     }
   }
 }
@@ -1569,7 +1611,6 @@ int greedy_default, greedy_non_default;
 int firstbyte, reqbyte;
 int zeroreqbyte, zerofirstbyte;
 int req_caseopt, reqvary, tempreqvary;
-int condcount = 0;
 int options = *optionsptr;
 int after_manual_callout = 0;
 register int c;
@@ -1683,10 +1724,14 @@ for (;; ptr++)
     if ((cd->ctypes[c] & ctype_space) != 0) continue;
     if (c == '#')
       {
-      /* The space before the ; is to avoid a warning on a silly compiler
-      on the Macintosh. */
-      while ((c = *(++ptr)) != 0 && c != NEWLINE) ;
-      if (c != 0) continue;   /* Else fall through to handle end of string */
+      while (*(++ptr) != 0) if (IS_NEWLINE(ptr)) break;
+      if (*ptr != 0)
+        {
+        ptr += cd->nllen - 1;
+        continue;
+        }
+      /* Else fall through to handle end of string */
+      c = 0;
       }
     }
 
@@ -2851,37 +2896,91 @@ for (;; ptr++)
         case '(':
         bravalue = OP_COND;       /* Conditional group */
 
-        /* Condition to test for recursion */
-
-        if (ptr[1] == 'R')
+        /* A condition can be a number, referring to a numbered group, a name,
+        referring to a named group, 'R', referring to recursion, or an
+        assertion. There are two unfortunate ambiguities, caused by history.
+        (a) 'R' can be the recursive thing or the name 'R', and (b) a number
+        could be a name that consists of digits. In both cases, we look for a
+        name first; if not found, we try the other cases. If the first
+        character after (?( is a word character, we know the rest up to ) will
+        also be word characters because the syntax was checked in the first
+        pass. */
+
+        if ((cd->ctypes[ptr[1]] & ctype_word) != 0)
           {
-          code[1+LINK_SIZE] = OP_CREF;
-          PUT2(code, 2+LINK_SIZE, CREF_RECURSE);
+          int i, namelen;
+          int condref = 0;
+          const uschar *name;
+          uschar *slot = cd->name_table;
+
+          /* This is needed for all successful cases. */
+
           skipbytes = 3;
-          ptr += 3;
-          }
 
-        /* Condition to test for a numbered subpattern match. We know that
-        if a digit follows ( then there will just be digits until ) because
-        the syntax was checked in the first pass. */
+          /* Read the name, but also get it as a number if it's all digits */
 
-        else if ((digitab[ptr[1]] && ctype_digit) != 0)
-          {
-          int condref;                 /* Don't amalgamate; some compilers */
-          condref = *(++ptr) - '0';    /* grumble at autoincrement in declaration */
-          while (*(++ptr) != ')') condref = condref*10 + *ptr - '0';
-          if (condref == 0)
+          name = ++ptr;
+          while (*ptr != ')')
             {
-            *errorcodeptr = ERR35;
-            goto FAILED;
+            if (condref >= 0)
+              condref = ((digitab[*ptr] & ctype_digit) != 0)?
+                condref * 10 + *ptr - '0' : -1;
+            ptr++;
             }
+          namelen = ptr - name;
           ptr++;
-          code[1+LINK_SIZE] = OP_CREF;
-          PUT2(code, 2+LINK_SIZE, condref);
-          skipbytes = 3;
+
+          for (i = 0; i < cd->names_found; i++)
+            {
+            if (strncmp((char *)name, (char *)slot+2, namelen) == 0) break;
+            slot += cd->name_entry_size;
+            }
+
+          /* Found a previous named subpattern */
+
+          if (i < cd->names_found)
+            {
+            condref = GET2(slot, 0);
+            code[1+LINK_SIZE] = OP_CREF;
+            PUT2(code, 2+LINK_SIZE, condref);
+            }
+
+          /* Search the pattern for a forward reference */
+
+          else if ((i = find_named_parens(ptr, *brackets, name, namelen)) > 0)
+            {
+            code[1+LINK_SIZE] = OP_CREF;
+            PUT2(code, 2+LINK_SIZE, i);
+            }
+
+          /* Check for 'R' for recursion */
+
+          else if (namelen == 1 && *name == 'R')
+            {
+            code[1+LINK_SIZE] = OP_CREF;
+            PUT2(code, 2+LINK_SIZE, CREF_RECURSE);
+            }
+
+          /* Check for a subpattern number */
+
+          else if (condref > 0)
+            {
+            code[1+LINK_SIZE] = OP_CREF;
+            PUT2(code, 2+LINK_SIZE, condref);
+            }
+
+          /* Either an unidentified subpattern, or a reference to (?(0) */
+
+          else
+            {
+            *errorcodeptr = (condref == 0)? ERR35: ERR15;
+            goto FAILED;
+            }
           }
+
         /* For conditions that are assertions, we just fall through, having
         set bravalue above. */
+
         break;
 
         case '=':                 /* Positive lookahead */
@@ -2953,10 +3052,13 @@ for (;; ptr++)
               {
               if (slot[2+namelen] == 0)
                 {
-                *errorcodeptr = ERR43;
-                goto FAILED;
+                if ((options & PCRE_DUPNAMES) == 0)
+                  {
+                  *errorcodeptr = ERR43;
+                  goto FAILED;
+                  }
                 }
-              crc = -1;             /* Current name is substring */
+              else crc = -1;      /* Current name is substring */
               }
             if (crc < 0)
               {
@@ -2989,14 +3091,18 @@ for (;; ptr++)
             if (strncmp((char *)name, (char *)slot+2, namelen) == 0) break;
             slot += cd->name_entry_size;
             }
-          if (i >= cd->names_found)
+
+          if (i < cd->names_found)         /* Back reference */
+            {
+            recno = GET2(slot, 0);
+            }
+          else if ((recno =                /* Forward back reference */
+                    find_named_parens(ptr, *brackets, name, namelen)) <= 0)
             {
             *errorcodeptr = ERR15;
             goto FAILED;
             }
 
-          recno = GET2(slot, 0);
-
           if (type == '>') goto HANDLE_RECURSION;  /* A few lines below */
 
           /* Back reference */
@@ -3036,9 +3142,8 @@ for (;; ptr++)
           regex in case it doesn't exist. */
 
           *code = OP_END;
-          called = (recno == 0)?
-            cd->start_code : find_bracket(cd->start_code, utf8, recno);
-
+          called = (recno == 0)? cd->start_code :
+            find_bracket(cd->start_code, utf8, recno);
           if (called == NULL)
             {
             *errorcodeptr = ERR15;
@@ -3085,6 +3190,7 @@ for (;; ptr++)
             case '-': optset = &unset; break;
 
             case 'i': *optset |= PCRE_CASELESS; break;
+            case 'J': *optset |= PCRE_DUPNAMES; break;
             case 'm': *optset |= PCRE_MULTILINE; break;
             case 's': *optset |= PCRE_DOTALL; break;
             case 'x': *optset |= PCRE_EXTENDED; break;
@@ -3201,7 +3307,7 @@ for (;; ptr++)
     else if (bravalue == OP_COND)
       {
       uschar *tc = code;
-      condcount = 0;
+      int condcount = 0;
 
       do {
          condcount++;
@@ -3906,13 +4012,14 @@ return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
 }
 
 
+
 PCRE_DATA_SCOPE pcre *
 pcre_compile2(const char *pattern, int options, int *errorcodeptr,
   const char **errorptr, int *erroroffset, const unsigned char *tables)
 {
 real_pcre *re;
 int length = 1 + LINK_SIZE;      /* For initial BRA plus length */
-int c, firstbyte, reqbyte;
+int c, firstbyte, reqbyte, newline;
 int bracount = 0;
 int branch_extra = 0;
 int branch_newextra;
@@ -3933,6 +4040,7 @@ uschar *code;
 const uschar *codestart;
 const uschar *ptr;
 compile_data compile_block;
+compile_data *cd = &compile_block;
 int brastack[BRASTACK_SIZE];
 uschar bralenstack[BRASTACK_SIZE];
 
@@ -3986,18 +4094,42 @@ if ((options & ~PUBLIC_OPTIONS) != 0)
 /* Set up pointers to the individual character tables */
 
 if (tables == NULL) tables = _pcre_default_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;
+cd->lcc = tables + lcc_offset;
+cd->fcc = tables + fcc_offset;
+cd->cbits = tables + cbits_offset;
+cd->ctypes = tables + ctypes_offset;
+
+/* Handle different types of newline. The two bits give four cases. The current
+code allows for one- or two-byte sequences. */
+
+switch (options & PCRE_NEWLINE_CRLF)
+  {
+  default:              newline = NEWLINE; break;   /* Compile-time default */
+  case PCRE_NEWLINE_CR: newline = '\r'; break;
+  case PCRE_NEWLINE_LF: newline = '\n'; break;
+  case PCRE_NEWLINE_CR+
+       PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;
+  }
+
+if (newline > 255)
+  {
+  cd->nllen = 2;
+  cd->nl[0] = (newline >> 8) & 255;
+  cd->nl[1] = newline & 255;
+  }
+else
+  {
+  cd->nllen = 1;
+  cd->nl[0] = newline;
+  }
 
 /* Maximum back reference and backref bitmap. This is updated for numeric
 references during the first pass, but for named references during the actual
 compile pass. The bitmap records up to 31 back references to help in deciding
 whether (.*) can be treated as anchored or not. */
 
-compile_block.top_backref = 0;
-compile_block.backref_map = 0;
+cd->top_backref = 0;
+cd->backref_map = 0;
 
 /* Reflect pattern for debugging output */
 
@@ -4031,14 +4163,16 @@ while ((c = *(++ptr)) != 0)
 
   if ((options & PCRE_EXTENDED) != 0)
     {
-    if ((compile_block.ctypes[c] & ctype_space) != 0) continue;
+    if ((cd->ctypes[c] & ctype_space) != 0) continue;
     if (c == '#')
       {
-      /* The space before the ; is to avoid a warning on a silly compiler
-      on the Macintosh. */
-      while ((c = *(++ptr)) != 0 && c != NEWLINE) ;
-      if (c == 0) break;
-      continue;
+      while (*(++ptr) != 0) if (IS_NEWLINE(ptr)) break;
+      if (*ptr != 0)
+        {
+        ptr += cd->nllen - 1;
+        continue;
+        }
+      break;    /* End loop at end of pattern */
       }
     }
 
@@ -4128,9 +4262,9 @@ while ((c = *(++ptr)) != 0)
     if (c <= -ESC_REF)
       {
       int refnum = -c - ESC_REF;
-      compile_block.backref_map |= (refnum < 32)? (1 << refnum) : 1;
-      if (refnum > compile_block.top_backref)
-        compile_block.top_backref = refnum;
+      cd->backref_map |= (refnum < 32)? (1 << refnum) : 1;
+      if (refnum > cd->top_backref)
+        cd->top_backref = refnum;
       length += 2;   /* For single back reference */
       if (ptr[1] == '{' && is_counted_repeat(ptr+2))
         {
@@ -4284,7 +4418,9 @@ while ((c = *(++ptr)) != 0)
       /* Check the syntax for POSIX stuff. The bits we actually handle are
       checked during the real compile phase. */
 
-      else if (*ptr == '[' && check_posix_syntax(ptr, &ptr, &compile_block))
+      else if (*ptr == '[' &&
+                (ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') &&
+                check_posix_syntax(ptr, &ptr, cd))
         {
         ptr++;
         class_optcount = 10;    /* Make sure > 1 */
@@ -4517,6 +4653,61 @@ while ((c = *(++ptr)) != 0)
         ptr += 2;
         break;
 
+        /* Named subpatterns are an extension copied from Python */
+
+        case 'P':
+        ptr += 3;
+
+        /* Handle the definition of a named subpattern */
+
+        if (*ptr == '<')
+          {
+          const uschar *p;    /* Don't amalgamate; some compilers */
+          p = ++ptr;          /* grumble at autoincrement in declaration */
+          while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
+          if (*ptr != '>')
+            {
+            errorcode = ERR42;
+            goto PCRE_ERROR_RETURN;
+            }
+          name_count++;
+          if (name_count > MAX_NAME_COUNT)
+            {
+            errorcode = ERR49;
+            goto PCRE_ERROR_RETURN;
+            }
+          if (ptr - p > max_name_size)
+            {
+            max_name_size = (ptr - p);
+            if (max_name_size > MAX_NAME_SIZE)
+              {
+              errorcode = ERR48;
+              goto PCRE_ERROR_RETURN;
+              }
+            }
+          capturing = TRUE;   /* Named parentheses are always capturing */
+          break;              /* Go handle capturing parentheses */
+          }
+
+        /* Handle back references and recursive calls to named subpatterns */
+
+        if (*ptr == '=' || *ptr == '>')
+          {
+          length += 3 + 3*LINK_SIZE;  /* Allow for the automatic "once" */
+          while ((cd->ctypes[*(++ptr)] & ctype_word) != 0);
+          if (*ptr != ')')
+            {
+            errorcode = ERR42;
+            goto PCRE_ERROR_RETURN;
+            }
+          goto RECURSE_CHECK_QUANTIFIED;
+          }
+
+        /* Unknown character after (?P */
+
+        errorcode = ERR41;
+        goto PCRE_ERROR_RETURN;
+
         /* (?R) specifies a recursive call to the regex, which is an extension
         to provide the facility which can be obtained by (?p{perl-code}) in
         Perl 5.6. In Perl 5.8 this has become (??{perl-code}).
@@ -4542,8 +4733,10 @@ while ((c = *(++ptr)) != 0)
 
         /* If this item is quantified, it will get wrapped inside brackets so
         as to use the code for quantified brackets. We jump down and use the
-        code that handles this for real brackets. */
+        code that handles this for real brackets. Come here from code for
+        named recursions/subroutines. */
 
+        RECURSE_CHECK_QUANTIFIED:
         if (ptr[1] == '+' || ptr[1] == '*' || ptr[1] == '?' || ptr[1] == '{')
           {
           length += 2 + 2 * LINK_SIZE;       /* to make bracketed */
@@ -4567,48 +4760,6 @@ while ((c = *(++ptr)) != 0)
         length += 2 + 2*LINK_SIZE;
         continue;
 
-        /* Named subpatterns are an extension copied from Python */
-
-        case 'P':
-        ptr += 3;
-
-        /* Handle the definition of a named subpattern */
-
-        if (*ptr == '<')
-          {
-          const uschar *p;    /* Don't amalgamate; some compilers */
-          p = ++ptr;          /* grumble at autoincrement in declaration */
-          while ((compile_block.ctypes[*ptr] & ctype_word) != 0) ptr++;
-          if (*ptr != '>')
-            {
-            errorcode = ERR42;
-            goto PCRE_ERROR_RETURN;
-            }
-          name_count++;
-          if (ptr - p > max_name_size) max_name_size = (ptr - p);
-          capturing = TRUE;   /* Named parentheses are always capturing */
-          break;
-          }
-
-        /* Handle back references and recursive calls to named subpatterns */
-
-        if (*ptr == '=' || *ptr == '>')
-          {
-          length += 2 + 2*LINK_SIZE;  /* Allow for the automatic "once" */
-          while ((compile_block.ctypes[*(++ptr)] & ctype_word) != 0);
-          if (*ptr != ')')
-            {
-            errorcode = ERR42;
-            goto PCRE_ERROR_RETURN;
-            }
-          break;
-          }
-
-        /* Unknown character after (?P */
-
-        errorcode = ERR41;
-        goto PCRE_ERROR_RETURN;
-
         /* Lookbehinds are in Perl from version 5.005 */
 
         case '<':
@@ -4624,19 +4775,17 @@ while ((c = *(++ptr)) != 0)
 
         /* Conditionals are in Perl from version 5.005. The bracket must either
         be followed by a number (for bracket reference) or by an assertion
-        group, or (a PCRE extension) by 'R' for a recursion test. */
+        group. PCRE extends this by allowing a name to reference a named group;
+        unfortunately, previously 'R' was implemented for a recursion test.
+        When this is compiled, we look for the named group 'R' first. At this
+        point we just do a basic syntax check. */
 
         case '(':
-        if (ptr[3] == 'R' && ptr[4] == ')')
-          {
-          ptr += 4;
-          length += 3;
-          }
-        else if ((digitab[ptr[3]] & ctype_digit) != 0)
+        if ((cd->ctypes[ptr[3]] & ctype_word) != 0)
           {
           ptr += 4;
           length += 3;
-          while ((digitab[*ptr] & ctype_digit) != 0) ptr++;
+          while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
           if (*ptr != ')')
             {
             errorcode = ERR26;
@@ -4675,6 +4824,11 @@ while ((c = *(++ptr)) != 0)
             *optset |= PCRE_CASELESS;
             continue;
 
+            case 'J':
+            *optset |= PCRE_DUPNAMES;
+            options |= PCRE_JCHANGED;   /* Record that it changed */
+            continue;
+
             case 'm':
             *optset |= PCRE_MULTILINE;
             continue;
@@ -4740,16 +4894,13 @@ while ((c = *(++ptr)) != 0)
             will lead to an over-estimate on the length, but this shouldn't
             matter very much. We also have to allow for resetting options at
             the start of any alternations, which we do by setting
-            branch_newextra to 2. Finally, we record whether the case-dependent
-            flag ever changes within the regex. This is used by the "required
-            character" code. */
+            branch_newextra to 2. */
 
             case ':':
             if (((set|unset) & PCRE_IMS) != 0)
               {
               length += 4;
               branch_newextra = 2;
-              if (((set|unset) & PCRE_CASELESS) != 0) options |= PCRE_ICHANGED;
               }
             goto END_OPTIONS;
 
@@ -4829,6 +4980,12 @@ while ((c = *(++ptr)) != 0)
       {
       duplength = length - brastack[--brastackptr];
       branch_extra = bralenstack[brastackptr];
+      /* This is a paranoid check to stop integer overflow later on */
+      if (duplength > MAX_DUPLENGTH)
+        {
+        errorcode = ERR50;
+        goto PCRE_ERROR_RETURN;
+        }
       }
     else duplength = 0;
 
@@ -4933,7 +5090,8 @@ if (length > MAX_PATTERN_SIZE)
   }
 
 /* Compute the size of data block needed and get it, either from malloc or
-externally provided function. */
+externally provided function. Integer overflow should no longer be possible
+because nowadays we limit the maximum value of name_count and max_name size. */
 
 size = length + sizeof(real_pcre) + name_count * (max_name_size + 3);
 re = (real_pcre *)(pcre_malloc)(size);
@@ -4963,14 +5121,14 @@ re->nullpad = NULL;
 /* The starting points of the name/number translation table and of the code are
 passed around in the compile data block. */
 
-compile_block.names_found = 0;
-compile_block.name_entry_size = max_name_size + 3;
-compile_block.name_table = (uschar *)re + re->name_table_offset;
-codestart = compile_block.name_table + re->name_entry_size * re->name_count;
-compile_block.start_code = codestart;
-compile_block.start_pattern = (const uschar *)pattern;
-compile_block.req_varyopt = 0;
-compile_block.nopartial = FALSE;
+cd->names_found = 0;
+cd->name_entry_size = max_name_size + 3;
+cd->name_table = (uschar *)re + re->name_table_offset;
+codestart = cd->name_table + re->name_entry_size * re->name_count;
+cd->start_code = codestart;
+cd->start_pattern = (const uschar *)pattern;
+cd->req_varyopt = 0;
+cd->nopartial = FALSE;
 
 /* Set up a starting, non-extracting bracket, then compile the expression. On
 error, errorcode will be set non-zero, so we don't need to look at the result
@@ -4981,11 +5139,11 @@ code = (uschar *)codestart;
 *code = OP_BRA;
 bracount = 0;
 (void)compile_regex(options, options & PCRE_IMS, &bracount, &code, &ptr,
-  &errorcode, FALSE, 0, &firstbyte, &reqbyte, NULL, &compile_block);
+  &errorcode, FALSE, 0, &firstbyte, &reqbyte, NULL, cd);
 re->top_bracket = bracount;
-re->top_backref = compile_block.top_backref;
+re->top_backref = cd->top_backref;
 
-if (compile_block.nopartial) re->options |= PCRE_NOPARTIAL;
+if (cd->nopartial) re->options |= PCRE_NOPARTIAL;
 
 /* If not reached end of pattern on success, there's an excess bracket. */
 
@@ -5031,7 +5189,7 @@ start with ^. and also when all branches start with .* for non-DOTALL matches.
 if ((options & PCRE_ANCHORED) == 0)
   {
   int temp_options = options;
-  if (is_anchored(codestart, &temp_options, 0, compile_block.backref_map))
+  if (is_anchored(codestart, &temp_options, 0, cd->backref_map))
     re->options |= PCRE_ANCHORED;
   else
     {
@@ -5041,10 +5199,10 @@ if ((options & PCRE_ANCHORED) == 0)
       {
       int ch = firstbyte & 255;
       re->first_byte = ((firstbyte & REQ_CASELESS) != 0 &&
-         compile_block.fcc[ch] == ch)? ch : firstbyte;
+         cd->fcc[ch] == ch)? ch : firstbyte;
       re->options |= PCRE_FIRSTSET;
       }
-    else if (is_startline(codestart, 0, compile_block.backref_map))
+    else if (is_startline(codestart, 0, cd->backref_map))
       re->options |= PCRE_STARTLINE;
     }
   }
@@ -5058,7 +5216,7 @@ if (reqbyte >= 0 &&
   {
   int ch = reqbyte & 255;
   re->req_byte = ((reqbyte & REQ_CASELESS) != 0 &&
-    compile_block.fcc[ch] == ch)? (reqbyte & ~REQ_CASELESS) : reqbyte;
+    cd->fcc[ch] == ch)? (reqbyte & ~REQ_CASELESS) : reqbyte;
   re->options |= PCRE_REQCHSET;
   }
 
@@ -5072,11 +5230,10 @@ printf("Length = %d top_bracket = %d top_backref = %d\n",
 
 if (re->options != 0)
   {
-  printf("%s%s%s%s%s%s%s%s%s%s\n",
+  printf("%s%s%s%s%s%s%s%s%s\n",
     ((re->options & PCRE_NOPARTIAL) != 0)? "nopartial " : "",
     ((re->options & PCRE_ANCHORED) != 0)? "anchored " : "",
     ((re->options & PCRE_CASELESS) != 0)? "caseless " : "",
-    ((re->options & PCRE_ICHANGED) != 0)? "case state changed " : "",
     ((re->options & PCRE_EXTENDED) != 0)? "extended " : "",
     ((re->options & PCRE_MULTILINE) != 0)? "multiline " : "",
     ((re->options & PCRE_DOTALL) != 0)? "dotall " : "",
index ecb32977df4c37686c1e11a64cd9ba423f30b145..882a1d1c0650063ac0028207fa142ba3aca94fad 100644 (file)
@@ -42,7 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
 pattern matching using an NFA algorithm, trying to mimic Perl as closely as
 possible. There are also some static supporting functions. */
 
-
+#define NLBLOCK md           /* The block containing newline information */
 #include "pcre_internal.h"
 
 
@@ -275,7 +275,7 @@ typedef struct heapframe {
   long int Xims;
   eptrblock *Xeptrb;
   int Xflags;
-  int Xrdepth;
+  unsigned int Xrdepth;
 
   /* Function local variables */
 
@@ -374,16 +374,16 @@ Returns:       MATCH_MATCH if matched            )  these values are >= 0
 static int
 match(REGISTER USPTR eptr, REGISTER const uschar *ecode,
   int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,
-  int flags, int rdepth)
+  int flags, unsigned int rdepth)
 {
 /* These variables do not need to be preserved over recursion in this function,
 so they can be ordinary variables in all cases. Mark them with "register"
 because they are used a lot in loops. */
 
-register int  rrc;    /* Returns from recursive calls */
-register int  i;      /* Used for loops not involving calls to RMATCH() */
-register int  c;      /* Character values not kept over RMATCH() calls */
-register BOOL utf8;   /* Local copy of UTF-8 flag for speed */
+register int  rrc;         /* Returns from recursive calls */
+register int  i;           /* Used for loops not involving calls to RMATCH() */
+register unsigned int  c;  /* Character values not kept over RMATCH() calls */
+register BOOL utf8;        /* Local copy of UTF-8 flag for speed */
 
 /* When recursion is not being used, all "local" variables that have to be
 preserved over calls to RMATCH() are part of a "frame" which is obtained from
@@ -527,6 +527,13 @@ prop_fail_result = 0;
 prop_test_variable = NULL;
 #endif
 
+/* This label is used for tail recursion, which is used in a few cases even
+when NO_RECURSE is not defined, in order to reduce the amount of stack that is
+used. Thanks to Ian Taylor for noticing this possibility and sending the
+original patch. */
+
+TAIL_RECURSE:
+
 /* OK, now we can get on with the real code of the function. Recursive calls
 are specified by the macro RMATCH and RRETURN is used to return. When
 NO_RECURSE is *not* defined, these just turn into a recursive call to match()
@@ -542,7 +549,12 @@ if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT);
 if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT);
 
 original_ims = ims;    /* Save for resetting on ')' */
+
+#ifdef SUPPORT_UTF8
 utf8 = md->utf8;       /* Local copy of the flag */
+#else
+utf8 = FALSE;
+#endif
 
 /* At the start of a bracketed group, add the current subject pointer to the
 stack of such pointers, to be re-instated at the end of the group when we hit
@@ -642,21 +654,38 @@ for (;;)
     {
     case OP_BRA:     /* Non-capturing bracket: optimized */
     DPRINTF(("start bracket 0\n"));
-    do
+
+    /* Loop for all the alternatives */
+
+    for (;;)
       {
+      /* When we get to the final alternative within the brackets, we would
+      return the result of a recursive call to match() whatever happened. We
+      can reduce stack usage by turning this into a tail recursion. */
+
+      if (ecode[GET(ecode, 1)] != OP_ALT)
+       {
+       ecode += 1 + LINK_SIZE;
+       flags = match_isgroup;
+       DPRINTF(("bracket 0 tail recursion\n"));
+       goto TAIL_RECURSE;
+       }
+
+      /* For non-final alternatives, continue the loop for a NOMATCH result;
+      otherwise return. */
+
       RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb,
         match_isgroup);
       if (rrc != MATCH_NOMATCH) RRETURN(rrc);
       ecode += GET(ecode, 1);
       }
-    while (*ecode == OP_ALT);
-    DPRINTF(("bracket 0 failed\n"));
-    RRETURN(MATCH_NOMATCH);
+    /* Control never reaches here. */
 
     /* Conditional group: compilation checked that there are no more than
     two branches. If the condition is false, skipping the first branch takes us
     past the end if there is only one branch, but that's OK because that is
-    exactly what going to the ket would do. */
+    exactly what going to the ket would do. As there is only one branch to be
+    obeyed, we can use tail recursion to avoid using another stack frame. */
 
     case OP_COND:
     if (ecode[LINK_SIZE+1] == OP_CREF) /* Condition extract or recurse test */
@@ -665,10 +694,9 @@ for (;;)
       condition = (offset == CREF_RECURSE * 2)?
         (md->recursive != NULL) :
         (offset < offset_top && md->offset_vector[offset] >= 0);
-      RMATCH(rrc, eptr, ecode + (condition?
-        (LINK_SIZE + 4) : (LINK_SIZE + 1 + GET(ecode, 1))),
-        offset_top, md, ims, eptrb, match_isgroup);
-      RRETURN(rrc);
+      ecode += condition? (LINK_SIZE + 4) : (LINK_SIZE + 1 + GET(ecode, 1));
+      flags = match_isgroup;
+      goto TAIL_RECURSE;
       }
 
     /* The condition is an assertion. Call match() to evaluate it - setting
@@ -688,9 +716,13 @@ for (;;)
         RRETURN(rrc);         /* Need braces because of following else */
         }
       else ecode += GET(ecode, 1);
-      RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb,
-        match_isgroup);
-      RRETURN(rrc);
+
+      /* We are now at the branch that is to be obeyed. As there is only one,
+      we can use tail recursion to avoid using another stack frame. */
+
+      ecode += 1 + LINK_SIZE;
+      flags = match_isgroup;
+      goto TAIL_RECURSE;
       }
     /* Control never reaches here */
 
@@ -945,71 +977,72 @@ for (;;)
     the end of a normal bracket, leaving the subject pointer. */
 
     case OP_ONCE:
-      {
-      prev = ecode;
-      saved_eptr = eptr;
+    prev = ecode;
+    saved_eptr = eptr;
 
-      do
-        {
-        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims,
-          eptrb, match_isgroup);
-        if (rrc == MATCH_MATCH) break;
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        ecode += GET(ecode,1);
-        }
-      while (*ecode == OP_ALT);
+    do
+      {
+      RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims,
+        eptrb, match_isgroup);
+      if (rrc == MATCH_MATCH) break;
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      ecode += GET(ecode,1);
+      }
+    while (*ecode == OP_ALT);
 
-      /* If hit the end of the group (which could be repeated), fail */
+    /* If hit the end of the group (which could be repeated), fail */
 
-      if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
+    if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
 
-      /* Continue as from after the assertion, updating the offsets high water
-      mark, since extracts may have been taken. */
+    /* Continue as from after the assertion, updating the offsets high water
+    mark, since extracts may have been taken. */
 
-      do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+    do ecode += GET(ecode,1); while (*ecode == OP_ALT);
 
-      offset_top = md->end_offset_top;
-      eptr = md->end_match_ptr;
+    offset_top = md->end_offset_top;
+    eptr = md->end_match_ptr;
 
-      /* For a non-repeating ket, just continue at this level. This also
-      happens for a repeating ket if no characters were matched in the group.
-      This is the forcible breaking of infinite loops as implemented in Perl
-      5.005. If there is an options reset, it will get obeyed in the normal
-      course of events. */
+    /* For a non-repeating ket, just continue at this level. This also
+    happens for a repeating ket if no characters were matched in the group.
+    This is the forcible breaking of infinite loops as implemented in Perl
+    5.005. If there is an options reset, it will get obeyed in the normal
+    course of events. */
 
-      if (*ecode == OP_KET || eptr == saved_eptr)
-        {
-        ecode += 1+LINK_SIZE;
-        break;
-        }
+    if (*ecode == OP_KET || eptr == saved_eptr)
+      {
+      ecode += 1+LINK_SIZE;
+      break;
+      }
 
-      /* The repeating kets try the rest of the pattern or restart from the
-      preceding bracket, in the appropriate order. We need to reset any options
-      that changed within the bracket before re-running it, so check the next
-      opcode. */
+    /* The repeating kets try the rest of the pattern or restart from the
+    preceding bracket, in the appropriate order. The second "call" of match()
+    uses tail recursion, to avoid using another stack frame. We need to reset
+    any options that changed within the bracket before re-running it, so
+    check the next opcode. */
 
-      if (ecode[1+LINK_SIZE] == OP_OPT)
-        {
-        ims = (ims & ~PCRE_IMS) | ecode[4];
-        DPRINTF(("ims set to %02lx at group repeat\n", ims));
-        }
+    if (ecode[1+LINK_SIZE] == OP_OPT)
+      {
+      ims = (ims & ~PCRE_IMS) | ecode[4];
+      DPRINTF(("ims set to %02lx at group repeat\n", ims));
+      }
 
-      if (*ecode == OP_KETRMIN)
-        {
-        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0);
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup);
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        }
-      else  /* OP_KETRMAX */
-        {
-        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup);
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        }
+    if (*ecode == OP_KETRMIN)
+      {
+      RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0);
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      ecode = prev;
+      flags = match_isgroup;
+      goto TAIL_RECURSE;
+      }
+    else  /* OP_KETRMAX */
+      {
+      RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup);
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      ecode += 1 + LINK_SIZE;
+      flags = 0;
+      goto TAIL_RECURSE;
       }
-    RRETURN(MATCH_NOMATCH);
+    /* Control never gets here */
 
     /* An alternation is the end of a branch; scan along to find the end of the
     bracketed group and go to there. */
@@ -1053,114 +1086,114 @@ for (;;)
     case OP_KET:
     case OP_KETRMIN:
     case OP_KETRMAX:
-      {
-      prev = ecode - GET(ecode, 1);
-      saved_eptr = eptrb->epb_saved_eptr;
+    prev = ecode - GET(ecode, 1);
+    saved_eptr = eptrb->epb_saved_eptr;
 
-      /* Back up the stack of bracket start pointers. */
+    /* Back up the stack of bracket start pointers. */
 
-      eptrb = eptrb->epb_prev;
+    eptrb = eptrb->epb_prev;
 
-      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
-          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
-          *prev == OP_ONCE)
-        {
-        md->end_match_ptr = eptr;      /* For ONCE */
-        md->end_offset_top = offset_top;
-        RRETURN(MATCH_MATCH);
-        }
+    if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
+        *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
+        *prev == OP_ONCE)
+      {
+      md->end_match_ptr = eptr;      /* For ONCE */
+      md->end_offset_top = offset_top;
+      RRETURN(MATCH_MATCH);
+      }
 
-      /* In all other cases except a conditional group we have to check the
-      group number back at the start and if necessary complete handling an
-      extraction by setting the offsets and bumping the high water mark. */
+    /* In all other cases except a conditional group we have to check the
+    group number back at the start and if necessary complete handling an
+    extraction by setting the offsets and bumping the high water mark. */
 
-      if (*prev != OP_COND)
-        {
-        number = *prev - OP_BRA;
+    if (*prev != OP_COND)
+      {
+      number = *prev - OP_BRA;
 
-        /* For extended extraction brackets (large number), we have to fish out
-        the number from a dummy opcode at the start. */
+      /* For extended extraction brackets (large number), we have to fish out
+      the number from a dummy opcode at the start. */
 
-        if (number > EXTRACT_BASIC_MAX) number = GET2(prev, 2+LINK_SIZE);
-        offset = number << 1;
+      if (number > EXTRACT_BASIC_MAX) number = GET2(prev, 2+LINK_SIZE);
+      offset = number << 1;
 
 #ifdef DEBUG
-        printf("end bracket %d", number);
-        printf("\n");
+      printf("end bracket %d", number);
+      printf("\n");
 #endif
 
-        /* Test for a numbered group. This includes groups called as a result
-        of recursion. Note that whole-pattern recursion is coded as a recurse
-        into group 0, so it won't be picked up here. Instead, we catch it when
-        the OP_END is reached. */
+      /* Test for a numbered group. This includes groups called as a result
+      of recursion. Note that whole-pattern recursion is coded as a recurse
+      into group 0, so it won't be picked up here. Instead, we catch it when
+      the OP_END is reached. */
 
-        if (number > 0)
+      if (number > 0)
+        {
+        md->capture_last = number;
+        if (offset >= md->offset_max) md->offset_overflow = TRUE; else
           {
-          md->capture_last = number;
-          if (offset >= md->offset_max) md->offset_overflow = TRUE; else
-            {
-            md->offset_vector[offset] =
-              md->offset_vector[md->offset_end - number];
-            md->offset_vector[offset+1] = eptr - md->start_subject;
-            if (offset_top <= offset) offset_top = offset + 2;
-            }
+          md->offset_vector[offset] =
+            md->offset_vector[md->offset_end - number];
+          md->offset_vector[offset+1] = eptr - md->start_subject;
+          if (offset_top <= offset) offset_top = offset + 2;
+          }
 
-          /* Handle a recursively called group. Restore the offsets
-          appropriately and continue from after the call. */
+        /* Handle a recursively called group. Restore the offsets
+        appropriately and continue from after the call. */
 
-          if (md->recursive != NULL && md->recursive->group_num == number)
-            {
-            recursion_info *rec = md->recursive;
-            DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
-            md->recursive = rec->prevrec;
-            md->start_match = rec->save_start;
-            memcpy(md->offset_vector, rec->offset_save,
-              rec->saved_max * sizeof(int));
-            ecode = rec->after_call;
-            ims = original_ims;
-            break;
-            }
+        if (md->recursive != NULL && md->recursive->group_num == number)
+          {
+          recursion_info *rec = md->recursive;
+          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
+          md->recursive = rec->prevrec;
+          md->start_match = rec->save_start;
+          memcpy(md->offset_vector, rec->offset_save,
+            rec->saved_max * sizeof(int));
+          ecode = rec->after_call;
+          ims = original_ims;
+          break;
           }
         }
+      }
 
-      /* Reset the value of the ims flags, in case they got changed during
-      the group. */
+    /* Reset the value of the ims flags, in case they got changed during
+    the group. */
 
-      ims = original_ims;
-      DPRINTF(("ims reset to %02lx\n", ims));
+    ims = original_ims;
+    DPRINTF(("ims reset to %02lx\n", ims));
 
-      /* For a non-repeating ket, just continue at this level. This also
-      happens for a repeating ket if no characters were matched in the group.
-      This is the forcible breaking of infinite loops as implemented in Perl
-      5.005. If there is an options reset, it will get obeyed in the normal
-      course of events. */
+    /* For a non-repeating ket, just continue at this level. This also
+    happens for a repeating ket if no characters were matched in the group.
+    This is the forcible breaking of infinite loops as implemented in Perl
+    5.005. If there is an options reset, it will get obeyed in the normal
+    course of events. */
 
-      if (*ecode == OP_KET || eptr == saved_eptr)
-        {
-        ecode += 1 + LINK_SIZE;
-        break;
-        }
+    if (*ecode == OP_KET || eptr == saved_eptr)
+      {
+      ecode += 1 + LINK_SIZE;
+      break;
+      }
 
-      /* The repeating kets try the rest of the pattern or restart from the
-      preceding bracket, in the appropriate order. */
+    /* The repeating kets try the rest of the pattern or restart from the
+    preceding bracket, in the appropriate order. In the second case, we can use
+    tail recursion to avoid using another stack frame. */
 
-      if (*ecode == OP_KETRMIN)
-        {
-        RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup);
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        }
-      else  /* OP_KETRMAX */
-        {
-        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup);
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        }
+    if (*ecode == OP_KETRMIN)
+      {
+      RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      ecode = prev;
+      flags = match_isgroup;
+      goto TAIL_RECURSE;
       }
-
-    RRETURN(MATCH_NOMATCH);
+    else  /* OP_KETRMAX */
+      {
+      RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup);
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      ecode += 1 + LINK_SIZE;
+      flags = 0;
+      goto TAIL_RECURSE;
+      }
+    /* Control never gets here */
 
     /* Start of subject unless notbol, or after internal newline if multiline */
 
@@ -1168,7 +1201,10 @@ for (;;)
     if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
     if ((ims & PCRE_MULTILINE) != 0)
       {
-      if (eptr != md->start_subject && eptr[-1] != NEWLINE)
+      if (eptr != md->start_subject &&
+          (eptr == md->end_subject ||
+           eptr < md->start_subject + md->nllen ||
+           !IS_NEWLINE(eptr - md->nllen)))
         RRETURN(MATCH_NOMATCH);
       ecode++;
       break;
@@ -1196,7 +1232,7 @@ for (;;)
     if ((ims & PCRE_MULTILINE) != 0)
       {
       if (eptr < md->end_subject)
-        { if (*eptr != NEWLINE) RRETURN(MATCH_NOMATCH); }
+        { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }
       else
         { if (md->noteol) RRETURN(MATCH_NOMATCH); }
       ecode++;
@@ -1207,14 +1243,14 @@ for (;;)
       if (md->noteol) RRETURN(MATCH_NOMATCH);
       if (!md->endonly)
         {
-        if (eptr < md->end_subject - 1 ||
-           (eptr == md->end_subject - 1 && *eptr != NEWLINE))
+        if (eptr != md->end_subject &&
+            (eptr != md->end_subject - md->nllen || !IS_NEWLINE(eptr)))
           RRETURN(MATCH_NOMATCH);
         ecode++;
         break;
         }
       }
-    /* ... else fall through */
+    /* ... else fall through for endonly */
 
     /* End of subject assertion (\z) */
 
@@ -1226,8 +1262,9 @@ for (;;)
     /* End of subject or ending \n assertion (\Z) */
 
     case OP_EODN:
-    if (eptr < md->end_subject - 1 ||
-       (eptr == md->end_subject - 1 && *eptr != NEWLINE)) RRETURN(MATCH_NOMATCH);
+    if (eptr != md->end_subject &&
+        (eptr != md->end_subject - md->nllen || !IS_NEWLINE(eptr)))
+      RRETURN(MATCH_NOMATCH);
     ecode++;
     break;
 
@@ -1280,13 +1317,14 @@ for (;;)
     /* Match a single character type; inline for speed */
 
     case OP_ANY:
-    if ((ims & PCRE_DOTALL) == 0 && eptr < md->end_subject && *eptr == NEWLINE)
-      RRETURN(MATCH_NOMATCH);
+    if ((ims & PCRE_DOTALL) == 0)
+      {
+      if (eptr <= md->end_subject - md->nllen && IS_NEWLINE(eptr))
+        RRETURN(MATCH_NOMATCH);
+      }
     if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);
-#ifdef SUPPORT_UTF8
     if (utf8)
       while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
-#endif
     ecode++;
     break;
 
@@ -2573,8 +2611,11 @@ for (;;)
         for (i = 1; i <= min; i++)
           {
           if (eptr >= md->end_subject ||
-             (*eptr++ == NEWLINE && (ims & PCRE_DOTALL) == 0))
+               ((ims & PCRE_DOTALL) == 0 &&
+                 eptr <= md->end_subject - md->nllen &&
+                 IS_NEWLINE(eptr)))
             RRETURN(MATCH_NOMATCH);
+          eptr++;
           while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
           }
         break;
@@ -2659,7 +2700,11 @@ for (;;)
         if ((ims & PCRE_DOTALL) == 0)
           {
           for (i = 1; i <= min; i++)
-            if (*eptr++ == NEWLINE) RRETURN(MATCH_NOMATCH);
+            {
+            if (eptr <= md->end_subject - md->nllen && IS_NEWLINE(eptr))
+              RRETURN(MATCH_NOMATCH);
+            eptr++;
+            }
           }
         else eptr += min;
         break;
@@ -2829,13 +2874,15 @@ for (;;)
           {
           RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
+          if (fi >= max || eptr >= md->end_subject ||
+               (ctype == OP_ANY && (ims & PCRE_DOTALL) == 0 &&
+                eptr <= md->end_subject - md->nllen && IS_NEWLINE(eptr)))
+            RRETURN(MATCH_NOMATCH);
 
           GETCHARINC(c, eptr);
           switch(ctype)
             {
-            case OP_ANY:
-            if ((ims & PCRE_DOTALL) == 0 && c == NEWLINE) RRETURN(MATCH_NOMATCH);
+            case OP_ANY:        /* This is the DOTALL case */
             break;
 
             case OP_ANYBYTE:
@@ -2884,12 +2931,15 @@ for (;;)
           {
           RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
+          if (fi >= max || eptr >= md->end_subject ||
+               ((ims & PCRE_DOTALL) == 0 &&
+                 eptr <= md->end_subject - md->nllen && IS_NEWLINE(eptr)))
+            RRETURN(MATCH_NOMATCH);
+
           c = *eptr++;
           switch(ctype)
             {
-            case OP_ANY:
-            if ((ims & PCRE_DOTALL) == 0 && c == NEWLINE) RRETURN(MATCH_NOMATCH);
+            case OP_ANY:   /* This is the DOTALL case */
             break;
 
             case OP_ANYBYTE:
@@ -3075,9 +3125,9 @@ for (;;)
           {
           case OP_ANY:
 
-          /* Special code is required for UTF8, but when the maximum is unlimited
-          we don't need it, so we repeat the non-UTF8 code. This is probably
-          worth it, because .* is quite a common idiom. */
+          /* Special code is required for UTF8, but when the maximum is
+          unlimited we don't need it, so we repeat the non-UTF8 code. This is
+          probably worth it, because .* is quite a common idiom. */
 
           if (max < INT_MAX)
             {
@@ -3085,7 +3135,9 @@ for (;;)
               {
               for (i = min; i < max; i++)
                 {
-                if (eptr >= md->end_subject || *eptr == NEWLINE) break;
+                if (eptr >= md->end_subject ||
+                    (eptr <= md->end_subject - md->nllen && IS_NEWLINE(eptr)))
+                  break;
                 eptr++;
                 while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
                 }
@@ -3094,6 +3146,7 @@ for (;;)
               {
               for (i = min; i < max; i++)
                 {
+                if (eptr >= md->end_subject) break;
                 eptr++;
                 while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
                 }
@@ -3108,7 +3161,9 @@ for (;;)
               {
               for (i = min; i < max; i++)
                 {
-                if (eptr >= md->end_subject || *eptr == NEWLINE) break;
+                if (eptr >= md->end_subject ||
+                    (eptr <= md->end_subject - md->nllen && IS_NEWLINE(eptr)))
+                  break;
                 eptr++;
                 }
               break;
@@ -3222,7 +3277,9 @@ for (;;)
             {
             for (i = min; i < max; i++)
               {
-              if (eptr >= md->end_subject || *eptr == NEWLINE) break;
+              if (eptr >= md->end_subject ||
+                  (eptr <= md->end_subject - md->nllen && IS_NEWLINE(eptr)))
+                break;
               eptr++;
               }
             break;
@@ -3419,7 +3476,8 @@ int rc, resetcount, ocount;
 int first_byte = -1;
 int req_byte = -1;
 int req_byte2 = -1;
-unsigned long int ims = 0;
+int newline;
+unsigned long int ims;
 BOOL using_temporary_offsets = FALSE;
 BOOL anchored;
 BOOL startline;
@@ -3427,6 +3485,7 @@ BOOL firstline;
 BOOL first_byte_caseless = FALSE;
 BOOL req_byte_caseless = FALSE;
 match_data match_block;
+match_data *md = &match_block;
 const uschar *tables;
 const uschar *start_bits = NULL;
 USPTR start_match = (USPTR)subject + start_offset;
@@ -3451,9 +3510,9 @@ if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
 the default values. */
 
 study = NULL;
-match_block.match_limit = MATCH_LIMIT;
-match_block.match_limit_recursion = MATCH_LIMIT_RECURSION;
-match_block.callout_data = NULL;
+md->match_limit = MATCH_LIMIT;
+md->match_limit_recursion = MATCH_LIMIT_RECURSION;
+md->callout_data = NULL;
 
 /* The table pointer is always in native byte order. */
 
@@ -3465,11 +3524,11 @@ if (extra_data != NULL)
   if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
     study = (const pcre_study_data *)extra_data->study_data;
   if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0)
-    match_block.match_limit = extra_data->match_limit;
+    md->match_limit = extra_data->match_limit;
   if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
-    match_block.match_limit_recursion = extra_data->match_limit_recursion;
+    md->match_limit_recursion = extra_data->match_limit_recursion;
   if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
-    match_block.callout_data = extra_data->callout_data;
+    md->callout_data = extra_data->callout_data;
   if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
   }
 
@@ -3499,39 +3558,64 @@ firstline = (re->options & PCRE_FIRSTLINE) != 0;
 
 /* The code starts after the real_pcre block and the capture name table. */
 
-match_block.start_code = (const uschar *)external_re + re->name_table_offset +
+md->start_code = (const uschar *)external_re + re->name_table_offset +
   re->name_count * re->name_entry_size;
 
-match_block.start_subject = (USPTR)subject;
-match_block.start_offset = start_offset;
-match_block.end_subject = match_block.start_subject + length;
-end_subject = match_block.end_subject;
+md->start_subject = (USPTR)subject;
+md->start_offset = start_offset;
+md->end_subject = md->start_subject + length;
+end_subject = md->end_subject;
+
+md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
+md->utf8 = (re->options & PCRE_UTF8) != 0;
+
+md->notbol = (options & PCRE_NOTBOL) != 0;
+md->noteol = (options & PCRE_NOTEOL) != 0;
+md->notempty = (options & PCRE_NOTEMPTY) != 0;
+md->partial = (options & PCRE_PARTIAL) != 0;
+md->hitend = FALSE;
+
+md->recursive = NULL;                   /* No recursion at top level */
 
-match_block.endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
-match_block.utf8 = (re->options & PCRE_UTF8) != 0;
+md->lcc = tables + lcc_offset;
+md->ctypes = tables + ctypes_offset;
 
-match_block.notbol = (options & PCRE_NOTBOL) != 0;
-match_block.noteol = (options & PCRE_NOTEOL) != 0;
-match_block.notempty = (options & PCRE_NOTEMPTY) != 0;
-match_block.partial = (options & PCRE_PARTIAL) != 0;
-match_block.hitend = FALSE;
+/* Handle different types of newline. The two bits give four cases. If nothing
+is set at run time, whatever was used at compile time applies. */
 
-match_block.recursive = NULL;                   /* No recursion at top level */
+switch ((((options & PCRE_NEWLINE_CRLF) == 0)? re->options : options) &
+         PCRE_NEWLINE_CRLF)
+  {
+  default:              newline = NEWLINE; break;   /* Compile-time default */
+  case PCRE_NEWLINE_CR: newline = '\r'; break;
+  case PCRE_NEWLINE_LF: newline = '\n'; break;
+  case PCRE_NEWLINE_CR+
+       PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;
+  }
 
-match_block.lcc = tables + lcc_offset;
-match_block.ctypes = tables + ctypes_offset;
+if (newline > 255)
+  {
+  md->nllen = 2;
+  md->nl[0] = (newline >> 8) & 255;
+  md->nl[1] = newline & 255;
+  }
+else
+  {
+  md->nllen = 1;
+  md->nl[0] = newline;
+  }
 
 /* Partial matching is supported only for a restricted set of regexes at the
 moment. */
 
-if (match_block.partial && (re->options & PCRE_NOPARTIAL) != 0)
+if (md->partial && (re->options & PCRE_NOPARTIAL) != 0)
   return PCRE_ERROR_BADPARTIAL;
 
 /* Check a UTF-8 string if required. Unfortunately there's no way of passing
 back the character offset. */
 
 #ifdef SUPPORT_UTF8
-if (match_block.utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
+if (md->utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
   {
   if (_pcre_valid_utf8((uschar *)subject, length) >= 0)
     return PCRE_ERROR_BADUTF8;
@@ -3563,17 +3647,17 @@ ocount = offsetcount - (offsetcount % 3);
 if (re->top_backref > 0 && re->top_backref >= ocount/3)
   {
   ocount = re->top_backref * 3 + 3;
-  match_block.offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
-  if (match_block.offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
+  md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
+  if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
   using_temporary_offsets = TRUE;
   DPRINTF(("Got memory to hold back references\n"));
   }
-else match_block.offset_vector = offsets;
+else md->offset_vector = offsets;
 
-match_block.offset_end = ocount;
-match_block.offset_max = (2*ocount)/3;
-match_block.offset_overflow = FALSE;
-match_block.capture_last = -1;
+md->offset_end = ocount;
+md->offset_max = (2*ocount)/3;
+md->offset_overflow = FALSE;
+md->capture_last = -1;
 
 /* Compute the minimum number of offsets that we need to reset each time. Doing
 this makes a huge difference to execution time when there aren't many brackets
@@ -3586,9 +3670,9 @@ if (resetcount > offsetcount) resetcount = ocount;
 never be used unless previously set, but they get saved and restored, and so we
 initialize them to avoid reading uninitialized locations. */
 
-if (match_block.offset_vector != NULL)
+if (md->offset_vector != NULL)
   {
-  register int *iptr = match_block.offset_vector + ocount;
+  register int *iptr = md->offset_vector + ocount;
   register int *iend = iptr - resetcount/2 + 1;
   while (--iptr >= iend) *iptr = -1;
   }
@@ -3605,7 +3689,7 @@ if (!anchored)
     {
     first_byte = re->first_byte & 255;
     if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)
-      first_byte = match_block.lcc[first_byte];
+      first_byte = md->lcc[first_byte];
     }
   else
     if (!startline && study != NULL &&
@@ -3632,9 +3716,9 @@ do
 
   /* Reset the maximum number of extractions we might see. */
 
-  if (match_block.offset_vector != NULL)
+  if (md->offset_vector != NULL)
     {
-    register int *iptr = match_block.offset_vector;
+    register int *iptr = md->offset_vector;
     register int *iend = iptr + resetcount;
     while (iptr < iend) *iptr++ = -1;
     }
@@ -3648,7 +3732,7 @@ do
   if (firstline)
     {
     USPTR t = start_match;
-    while (t < save_end_subject && *t != '\n') t++;
+    while (t <= save_end_subject - md->nllen && !IS_NEWLINE(t)) t++;
     end_subject = t;
     }
 
@@ -3658,20 +3742,22 @@ do
     {
     if (first_byte_caseless)
       while (start_match < end_subject &&
-             match_block.lcc[*start_match] != first_byte)
+             md->lcc[*start_match] != first_byte)
         start_match++;
     else
       while (start_match < end_subject && *start_match != first_byte)
         start_match++;
     }
 
-  /* Or to just after \n for a multiline match if possible */
+  /* Or to just after a linebreak for a multiline match if possible */
 
   else if (startline)
     {
-    if (start_match > match_block.start_subject + start_offset)
+    if (start_match >= md->start_subject + md->nllen +
+          start_offset)
       {
-      while (start_match < end_subject && start_match[-1] != NEWLINE)
+      while (start_match <= end_subject &&
+             !IS_NEWLINE(start_match - md->nllen))
         start_match++;
       }
     }
@@ -3693,7 +3779,7 @@ do
 
 #ifdef DEBUG  /* Sigh. Some compilers never learn. */
   printf(">>>> Match against: ");
-  pchars(start_match, end_subject - start_match, TRUE, &match_block);
+  pchars(start_match, end_subject - start_match, TRUE, md);
   printf("\n");
 #endif
 
@@ -3715,7 +3801,7 @@ do
 
   if (req_byte >= 0 &&
       end_subject - start_match < REQ_BYTE_MAX &&
-      !match_block.partial)
+      !md->partial)
     {
     register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);
 
@@ -3759,11 +3845,10 @@ do
   those back references that we can. In this case there need not be overflow
   if certain parts of the pattern were not used. */
 
-  match_block.start_match = start_match;
-  match_block.match_call_count = 0;
+  md->start_match = start_match;
+  md->match_call_count = 0;
 
-  rc = match(start_match, match_block.start_code, 2, &match_block, ims, NULL,
-    match_isgroup, 0);
+  rc = match(start_match, md->start_code, 2, md, ims, NULL, match_isgroup, 0);
 
   /* When the result is no match, if the subject's first character was a
   newline and the PCRE_FIRSTLINE option is set, break (which will return
@@ -3774,10 +3859,13 @@ do
 
   if (rc == MATCH_NOMATCH)
     {
-    if (firstline && *start_match == NEWLINE) break;
+    if (firstline &&
+        start_match <= md->end_subject - md->nllen &&
+        IS_NEWLINE(start_match))
+      break;
     start_match++;
 #ifdef SUPPORT_UTF8
-    if (match_block.utf8)
+    if (md->utf8)
       while(start_match < end_subject && (*start_match & 0xc0) == 0x80)
         start_match++;
 #endif
@@ -3797,23 +3885,23 @@ do
     {
     if (offsetcount >= 4)
       {
-      memcpy(offsets + 2, match_block.offset_vector + 2,
+      memcpy(offsets + 2, md->offset_vector + 2,
         (offsetcount - 2) * sizeof(int));
       DPRINTF(("Copied offsets from temporary memory\n"));
       }
-    if (match_block.end_offset_top > offsetcount)
-      match_block.offset_overflow = TRUE;
+    if (md->end_offset_top > offsetcount)
+      md->offset_overflow = TRUE;
 
     DPRINTF(("Freeing temporary memory\n"));
-    (pcre_free)(match_block.offset_vector);
+    (pcre_free)(md->offset_vector);
     }
 
-  rc = match_block.offset_overflow? 0 : match_block.end_offset_top/2;
+  rc = md->offset_overflow? 0 : md->end_offset_top/2;
 
   if (offsetcount < 2) rc = 0; else
     {
-    offsets[0] = start_match - match_block.start_subject;
-    offsets[1] = match_block.end_match_ptr - match_block.start_subject;
+    offsets[0] = start_match - md->start_subject;
+    offsets[1] = md->end_match_ptr - md->start_subject;
     }
 
   DPRINTF((">>>> returning %d\n", rc));
@@ -3827,10 +3915,10 @@ while (!anchored && start_match <= end_subject);
 if (using_temporary_offsets)
   {
   DPRINTF(("Freeing temporary memory\n"));
-  (pcre_free)(match_block.offset_vector);
+  (pcre_free)(md->offset_vector);
   }
 
-if (match_block.partial && match_block.hitend)
+if (md->partial && md->hitend)
   {
   DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
   return PCRE_ERROR_PARTIAL;
index 674625a0e9ab9fb0f6e3adc8f30f58102de23fec..0588c61a7f9cea304447526b52b4f4e13ba5e705 100644 (file)
@@ -50,8 +50,8 @@ for these functions came from Scott Wimer. */
 *           Find number for named string         *
 *************************************************/
 
-/* This function is used by the two extraction functions below, as well
-as being generally available.
+/* This function is used by the get_first_set() function below, as well
+as being generally available. It assumes that names are unique.
 
 Arguments:
   code        the compiled regex
@@ -93,6 +93,113 @@ return PCRE_ERROR_NOSUBSTRING;
 
 
 
+/*************************************************
+*     Find (multiple) entries for named string   *
+*************************************************/
+
+/* This is used by the get_first_set() function below, as well as being
+generally available. It is used when duplicated names are permitted.
+
+Arguments:
+  code        the compiled regex
+  stringname  the name whose entries required
+  firstptr    where to put the pointer to the first entry
+  lastptr     where to put the pointer to the last entry
+
+Returns:      the length of each entry, or a negative number
+                (PCRE_ERROR_NOSUBSTRING) if not found
+*/
+
+int
+pcre_get_stringtable_entries(const pcre *code, const char *stringname,
+  char **firstptr, char **lastptr)
+{
+int rc;
+int entrysize;
+int top, bot;
+uschar *nametable, *lastentry;
+
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+  return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+  return rc;
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+  return rc;
+
+lastentry = nametable + entrysize * (top - 1);
+bot = 0;
+while (top > bot)
+  {
+  int mid = (top + bot) / 2;
+  uschar *entry = nametable + entrysize*mid;
+  int c = strcmp(stringname, (char *)(entry + 2));
+  if (c == 0)
+    {
+    uschar *first = entry;
+    uschar *last = entry;
+    while (first > nametable)
+      {
+      if (strcmp(stringname, (char *)(first - entrysize + 2)) != 0) break;
+      first -= entrysize;
+      }
+    while (last < lastentry)
+      {
+      if (strcmp(stringname, (char *)(last + entrysize + 2)) != 0) break;
+      last += entrysize;
+      }
+    *firstptr = (char *)first;
+    *lastptr = (char *)last;
+    return entrysize;
+    }
+  if (c > 0) bot = mid + 1; else top = mid;
+  }
+
+return PCRE_ERROR_NOSUBSTRING;
+}
+
+
+
+/*************************************************
+*    Find first set of multiple named strings    *
+*************************************************/
+
+/* This function allows for duplicate names in the table of named substrings.
+It returns the number of the first one that was set in a pattern match.
+
+Arguments:
+  code         the compiled regex
+  stringname   the name of the capturing substring
+  ovector      the vector of matched substrings
+
+Returns:       the number of the first that is set,
+               or the number of the last one if none are set,
+               or a negative number on error
+*/
+
+static int
+get_first_set(const pcre *code, const char *stringname, int *ovector)
+{
+const real_pcre *re = (const real_pcre *)code;
+int entrysize;
+char *first, *last;
+uschar *entry;
+if ((re->options & (PCRE_DUPNAMES | PCRE_JCHANGED)) == 0)
+  return pcre_get_stringnumber(code, stringname);
+entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last);
+if (entrysize <= 0) return entrysize;
+for (entry = (uschar *)first; entry <= (uschar *)last; entry += entrysize)
+  {
+  int n = (entry[0] << 8) + entry[1];
+  if (ovector[n*2] >= 0) return n;
+  }
+return (first[0] << 8) + first[1];
+}
+
+
+
+
 /*************************************************
 *      Copy captured string to given buffer      *
 *************************************************/
@@ -142,7 +249,8 @@ return yield;
 *************************************************/
 
 /* This function copies a single captured substring into a given buffer,
-identifying it by name.
+identifying it by name. If the regex permits duplicate names, the first
+substring that is set is chosen.
 
 Arguments:
   code           the compiled regex
@@ -168,7 +276,7 @@ int
 pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector,
   int stringcount, const char *stringname, char *buffer, int size)
 {
-int n = pcre_get_stringnumber(code, stringname);
+int n = get_first_set(code, stringname, ovector);
 if (n <= 0) return n;
 return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
 }
@@ -299,7 +407,8 @@ return yield;
 *************************************************/
 
 /* This function copies a single captured substring, identified by name, into
-new store.
+new store. If the regex permits duplicate names, the first substring that is
+set is chosen.
 
 Arguments:
   code           the compiled regex
@@ -324,9 +433,10 @@ int
 pcre_get_named_substring(const pcre *code, const char *subject, int *ovector,
   int stringcount, const char *stringname, const char **stringptr)
 {
-int n = pcre_get_stringnumber(code, stringname);
+int n = get_first_set(code, stringname, ovector);
 if (n <= 0) return n;
 return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
+
 }
 
 
index 386ed3ddf94d9d0fe5fa909a90b274fb7ef05dd6..6f91020f90b4f4061cf3287439cee95046935aac 100644 (file)
@@ -118,6 +118,14 @@ Unix, where it is defined in sys/types, so use "uschar" instead. */
 
 typedef unsigned char uschar;
 
+/* PCRE is able to support 3 different kinds of newline (CR, LF, CRLF). The
+following macro is used to package up testing for newlines. NLBLOCK is defined
+in the various modules to indicate in which datablock the parameters exist. */
+
+#define IS_NEWLINE(p) \
+  ((p)[0] == NLBLOCK->nl[0] && \
+  (NLBLOCK->nllen == 1 || (p)[1] == NLBLOCK->nl[1]))
+
 /* When PCRE is compiled as a C++ library, the subject pointer can be replaced
 with a custom type. This makes it possible, for example, to allow pcre_exec()
 to process subject strings that are discontinuous by using a smart pointer
@@ -164,7 +172,7 @@ case in PCRE. */
 #if HAVE_BCOPY
 #define memmove(a, b, c) bcopy(b, a, c)
 #else  /* HAVE_BCOPY */
-void *
+static void *
 pcre_memmove(unsigned char *dest, const unsigned char *src, size_t n)
 {
 size_t i;
@@ -377,16 +385,17 @@ Standard C system should have one. */
 
 #define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL)
 
-/* Private options flags start at the most significant end of the four bytes,
-but skip the top bit so we can use ints for convenience without getting tangled
-with negative values. The public options defined in pcre.h start at the least
-significant end. Make sure they don't overlap! */
+/* Private options flags start at the most significant end of the four bytes.
+The public options defined in pcre.h start at the least significant end. Make
+sure they don't overlap! The bits are getting a bit scarce now -- when we run
+out, there is a dummy word in the structure that could be used for the private
+bits. */
 
+#define PCRE_NOPARTIAL     0x80000000  /* can't use partial with this regex */
 #define PCRE_FIRSTSET      0x40000000  /* first_byte is set */
 #define PCRE_REQCHSET      0x20000000  /* req_byte is set */
 #define PCRE_STARTLINE     0x10000000  /* start after \n for multiline */
-#define PCRE_ICHANGED      0x08000000  /* i option changes within regex */
-#define PCRE_NOPARTIAL     0x04000000  /* can't use partial with this regex */
+#define PCRE_JCHANGED      0x08000000  /* j option changes within regex */
 
 /* Options for the "extra" block produced by pcre_study(). */
 
@@ -398,15 +407,17 @@ time, run time, or study time, respectively. */
 #define PUBLIC_OPTIONS \
   (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
    PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \
-   PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE)
+   PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \
+   PCRE_DUPNAMES|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF)
 
 #define PUBLIC_EXEC_OPTIONS \
   (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK| \
-   PCRE_PARTIAL)
+   PCRE_PARTIAL|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF)
 
 #define PUBLIC_DFA_EXEC_OPTIONS \
   (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK| \
-   PCRE_PARTIAL|PCRE_DFA_SHORTEST|PCRE_DFA_RESTART)
+   PCRE_PARTIAL|PCRE_DFA_SHORTEST|PCRE_DFA_RESTART|PCRE_NEWLINE_CR| \
+   PCRE_NEWLINE_LF)
 
 #define PUBLIC_STUDY_OPTIONS 0   /* None defined */
 
@@ -534,7 +545,7 @@ enum {
   OP_DOLL,           /* 20 End of line - varies with multiline switch */
   OP_CHAR,           /* 21 Match one character, casefully */
   OP_CHARNC,         /* 22 Match one character, caselessly */
-  OP_NOT,            /* 23 Match anything but the following char */
+  OP_NOT,            /* 23 Match one character, not the following one */
 
   OP_STAR,           /* 24 The maximizing and minimizing versions of */
   OP_MINSTAR,        /* 25 all these opcodes must come in pairs, with */
@@ -714,7 +725,8 @@ enum { ERR0,  ERR1,  ERR2,  ERR3,  ERR4,  ERR5,  ERR6,  ERR7,  ERR8,  ERR9,
        ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19,
        ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29,
        ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39,
-       ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47 };
+       ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49,
+       ERR50, ERR51 };
 
 /* The real format of the start of the pcre block; the index of names and the
 code vector run on as long as necessary after the end. We store an explicit
@@ -778,6 +790,8 @@ typedef struct compile_data {
   unsigned int backref_map;     /* Bitmap of low back refs */
   int  req_varyopt;             /* "After variable item" flag for reqbyte */
   BOOL nopartial;               /* Set TRUE if partial won't work */
+  int  nllen;                   /* 1 or 2 for newline string length */
+  uschar nl[4];                 /* Newline string */
 } compile_data;
 
 /* Structure for maintaining a chain of pointers to the currently incomplete
@@ -802,11 +816,11 @@ typedef struct recursion_info {
 
 /* When compiling in a mode that doesn't use recursive calls to match(),
 a structure is used to remember local variables on the heap. It is defined in
-pcre.c, close to the match() function, so that it is easy to keep it in step
-with any changes of local variable. However, the pointer to the current frame
-must be saved in some "static" place over a longjmp(). We declare the
-structure here so that we can put a pointer in the match_data structure.
-NOTE: This isn't used for a "normal" compilation of pcre. */
+pcre_exec.c, close to the match() function, so that it is easy to keep it in
+step with any changes of local variable. However, the pointer to the current
+frame must be saved in some "static" place over a longjmp(). We declare the
+structure here so that we can put a pointer in the match_data structure. NOTE:
+This isn't used for a "normal" compilation of pcre. */
 
 struct heapframe;
 
@@ -820,6 +834,8 @@ typedef struct match_data {
   int   *offset_vector;         /* Offset vector */
   int    offset_end;            /* One past the end */
   int    offset_max;            /* The maximum usable for return data */
+  int    nllen;                 /* 1 or 2 for newline string length */
+  uschar nl[4];                 /* Newline string */
   const uschar *lcc;            /* Points to lower casing table */
   const uschar *ctypes;         /* Points to table of type maps */
   BOOL   offset_overflow;       /* Set if too many extractions */
@@ -853,6 +869,8 @@ typedef struct dfa_match_data {
   const uschar *tables;         /* Character tables */
   int   moptions;               /* Match options */
   int   poptions;               /* Pattern options */
+  int    nllen;                 /* 1 or 2 for newline string length */
+  uschar nl[4];                 /* Newline string */
   void  *callout_data;          /* To pass back to callouts */
 } dfa_match_data;
 
@@ -926,7 +944,7 @@ sense, but are not part of the PCRE public API. */
 extern int         _pcre_ord2utf8(int, uschar *);
 extern real_pcre * _pcre_try_flipped(const real_pcre *, real_pcre *,
                      const pcre_study_data *, pcre_study_data *);
-extern int         _pcre_ucp_findprop(const int, int *, int *);
+extern int         _pcre_ucp_findprop(const unsigned int, int *, int *);
 extern int         _pcre_ucp_othercase(const int);
 extern int         _pcre_valid_utf8(const uschar *, int);
 extern BOOL        _pcre_xclass(int, const uschar *);
index abc272f4989498f1c9addc2a00c0a28e2fdda874..afe63d1b1804b60ebb7788b5fd4a952baa275143 100644 (file)
@@ -130,7 +130,9 @@ for (i = 0; i < 256; i++)
   meta-character, which in this sense is any character that terminates a run
   of data characters. */
 
-  if (strchr("*+?{^.$|()[", i) != 0) x += ctype_meta; *p++ = x; }
+  if (strchr("*+?{^.$|()[", i) != 0) x += ctype_meta;
+  *p++ = x;
+  }
 
 return yield;
 }
index 34f52d114d9fe709840e2d0dd7e750957019c679..e4de825a9b90966ab340e4413b96f6e88a8ce072 100644 (file)
@@ -111,9 +111,9 @@ for (i = _pcre_utt_size; i >= 0; i--)
   }
 return (i >= 0)? _pcre_utt[i].name : "??";
 #else
-ptype = ptype;    /* Avoid compiler warning */
-pvalue = pvalue;
-return "??";
+/* It gets harder and harder to shut off unwanted compiler warnings. */
+ptype = ptype * pvalue;
+return (ptype == pvalue)? "??" : "??";
 #endif
 }
 
@@ -182,32 +182,26 @@ for(;;)
     break;
 
     case OP_CHAR:
+    fprintf(f, "    ");
+    do
       {
-      fprintf(f, "    ");
-      do
-        {
-        code++;
-        code += 1 + print_char(f, code, utf8);
-        }
-      while (*code == OP_CHAR);
-      fprintf(f, "\n");
-      continue;
+      code++;
+      code += 1 + print_char(f, code, utf8);
       }
-    break;
+    while (*code == OP_CHAR);
+    fprintf(f, "\n");
+    continue;
 
     case OP_CHARNC:
+    fprintf(f, " NC ");
+    do
       {
-      fprintf(f, " NC ");
-      do
-        {
-        code++;
-        code += 1 + print_char(f, code, utf8);
-        }
-      while (*code == OP_CHARNC);
-      fprintf(f, "\n");
-      continue;
+      code++;
+      code += 1 + print_char(f, code, utf8);
       }
-    break;
+    while (*code == OP_CHARNC);
+    fprintf(f, "\n");
+    continue;
 
     case OP_KETRMAX:
     case OP_KETRMIN:
index d3ea04ff7ef52375b225ed684190ccfdaf8095d6..5091324ae6c0512b1148e65f6f0e13e23d49bd20 100644 (file)
@@ -95,6 +95,13 @@ set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless,
 {
 register int c;
 
+#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
@@ -102,6 +109,8 @@ 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
   {
@@ -159,7 +168,11 @@ do
       case OP_BRAMINZERO:
       if (!set_start_bits(++tcode, start_bits, caseless, utf8, cd))
         return FALSE;
+/* =========================================================================
+      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;
@@ -215,15 +228,29 @@ do
       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++)
-        start_bits[c] |= ~cd->cbits[c+cbit_space];
+        {
+        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++)
-        start_bits[c] |= cd->cbits[c+cbit_space];
+        {
+        int d = cd->cbits[c+cbit_space];
+        if (c == 1) d &= ~0x08;
+        start_bits[c] |= d;
+        }
       try_next = FALSE;
       break;
 
@@ -277,14 +304,28 @@ do
           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++)
-          start_bits[c] |= ~cd->cbits[c+cbit_space];
+          {
+          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++)
-          start_bits[c] |= cd->cbits[c+cbit_space];
+          {
+          int d = cd->cbits[c+cbit_space];
+          if (c == 1) d &= ~0x08;
+          start_bits[c] |= d;
+          }
         break;
 
         case OP_NOT_WORDCHAR:
@@ -408,10 +449,9 @@ uschar start_bits[32];
 pcre_extra *extra;
 pcre_study_data *study;
 const uschar *tables;
-const real_pcre *re = (const real_pcre *)external_re;
-uschar *code = (uschar *)re + re->name_table_offset +
-  (re->name_count * re->name_entry_size);
+uschar *code;
 compile_data compile_block;
+const real_pcre *re = (const real_pcre *)external_re;
 
 *errorptr = NULL;
 
@@ -427,6 +467,9 @@ if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
   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. */
index 7174cb6e12d1ec844b0494d2fd4ac4a8e0c1ce8f..00c94fccf5560948243d27cfb8bd9dcdbd896ef5 100644 (file)
@@ -62,8 +62,8 @@ Arguments:
 Returns:       the flipped value
 */
 
-static long int
-byteflip(long int value, int n)
+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) |
index ac964ca903368480dbfbbad223021f6a8263522a..7a4be9486199795d7ea95ccfd244c472d8a156f2 100644 (file)
@@ -79,7 +79,7 @@ Returns:      the character type category
 */
 
 int
-_pcre_ucp_findprop(const int c, int *type_ptr, int *script_ptr)
+_pcre_ucp_findprop(const unsigned int c, int *type_ptr, int *script_ptr)
 {
 int bot = 0;
 int top = sizeof(ucp_table)/sizeof(cnode);
index 70d59a2723f6f8a424bac89ba8d38d72064b36a2..f828de732e26f6ff4a726c4cdad21e129b94fe08 100644 (file)
@@ -332,6 +332,30 @@ bool RE::Replace(const StringPiece& rewrite,
   return true;
 }
 
+// Returns PCRE_NEWLINE_CRLF, PCRE_NEWLINE_CR, or PCRE_NEWLINE_LF.
+// Note that PCRE_NEWLINE_CRLF is defined to be P_N_CR | P_N_LF.
+static int NewlineMode(int pcre_options) {
+  // TODO: if we can make it threadsafe, cache this var
+  int newline_mode = 0;
+  /* if (newline_mode) return newline_mode; */  // do this once it's cached
+  if (pcre_options & (PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF)) {
+    newline_mode = (pcre_options &
+                    (PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF));
+  } else {
+    int newline;
+    pcre_config(PCRE_CONFIG_NEWLINE, &newline);
+    if (newline == 10)
+      newline_mode = PCRE_NEWLINE_LF;
+    else if (newline == 13)
+      newline_mode = PCRE_NEWLINE_CR;
+    else if (newline == 3338)
+      newline_mode = PCRE_NEWLINE_CRLF;
+    else
+      assert("" == "Unexpected return value from pcre_config(NEWLINE)");
+  }
+  return newline_mode;
+}
+
 int RE::GlobalReplace(const StringPiece& rewrite,
                       string *str) const {
   int count = 0;
@@ -350,9 +374,27 @@ int RE::GlobalReplace(const StringPiece& rewrite,
     if (matchstart == matchend && matchstart == lastend) {
       // advance one character if we matched an empty string at the same
       // place as the last match occurred
-      if (start < static_cast<int>(str->length()))
-        out.push_back((*str)[start]);
-      start++;
+      matchend = start + 1;
+      // If the current char is CR and we're in CRLF mode, skip LF too.
+      // Note it's better to call pcre_fullinfo() than to examine
+      // all_options(), since options_ could have changed bewteen
+      // compile-time and now, but this is simpler and safe enough.
+      if (start+1 < static_cast<int>(str->length()) &&
+          (*str)[start] == '\r' && (*str)[start+1] == '\n' &&
+          NewlineMode(options_.all_options()) == PCRE_NEWLINE_CRLF) {
+        matchend++;
+      }
+      // We also need to advance more than one char if we're in utf8 mode.
+#ifdef SUPPORT_UTF8
+      if (options_.utf8()) {
+        while (matchend < static_cast<int>(str->length()) &&
+               ((*str)[matchend] & 0xc0) == 0x80)
+          matchend++;
+      }
+#endif
+      if (matchend <= static_cast<int>(str->length()))
+        out.append(*str, start, matchend - start);
+      start = matchend;
     } else {
       out.append(*str, start, matchstart - start);
       Rewrite(&out, rewrite, *str, vec, matches);
index ba808bc4f6eb413e6033a89f0aa04eb762150ad8..ccd876d0813fc138a83a2118a7a3f7799a90dc7d 100644 (file)
@@ -32,6 +32,7 @@
 // TODO: Test extractions for PartialMatch/Consume
 
 #include <stdio.h>
+#include <cassert>
 #include <vector>
 #include "config.h"
 #include "pcrecpp.h"
@@ -259,17 +260,71 @@ static void TestReplace() {
       "aaaaa",
       "bbaaaaa",
       "bbabbabbabbabbabb" },
+    { "b*",
+      "bb",
+      "aa\naa\n",
+      "bbaa\naa\n",
+      "bbabbabb\nbbabbabb\nbb" },
+    { "b*",
+      "bb",
+      "aa\raa\r",
+      "bbaa\raa\r",
+      "bbabbabb\rbbabbabb\rbb" },
+    { "b*",
+      "bb",
+      "aa\r\naa\r\n",
+      "bbaa\r\naa\r\n",
+      "bbabbabb\r\nbbabbabb\r\nbb" },
+#ifdef SUPPORT_UTF8
+    { "b*",
+      "bb",
+      "\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0\xE3\x81\xB8",   // utf8
+      "bb\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0\xE3\x81\xB8",
+      "bb\xE3\x83\x9B""bb""\xE3\x83\xBC""bb""\xE3\x83\xA0""bb""\xE3\x81\xB8""bb" },
+    { "b*",
+      "bb",
+      "\xE3\x83\x9B\r\n\xE3\x83\xBC\r\xE3\x83\xA0\n\xE3\x81\xB8\r\n",   // utf8
+      "bb\xE3\x83\x9B\r\n\xE3\x83\xBC\r\xE3\x83\xA0\n\xE3\x81\xB8\r\n",
+      ("bb\xE3\x83\x9B""bb\r\nbb""\xE3\x83\xBC""bb\rbb""\xE3\x83\xA0"
+       "bb\nbb""\xE3\x81\xB8""bb\r\nbb") },
+#endif
     { "", NULL, NULL, NULL, NULL }
   };
 
+#ifdef SUPPORT_UTF8
+  const bool support_utf8 = true;
+#else
+  const bool support_utf8 = false;
+#endif
+
   for (const ReplaceTest *t = tests; t->original != NULL; ++t) {
+    RE re(t->regexp, RE_Options(PCRE_NEWLINE_CRLF).set_utf8(support_utf8));
+    assert(re.error().empty());
     string one(t->original);
-    CHECK(RE(t->regexp).Replace(t->rewrite, &one));
+    CHECK(re.Replace(t->rewrite, &one));
     CHECK_EQ(one, t->single);
     string all(t->original);
-    CHECK(RE(t->regexp).GlobalReplace(t->rewrite, &all) > 0);
+    CHECK(re.GlobalReplace(t->rewrite, &all) > 0);
     CHECK_EQ(all, t->global);
   }
+
+  // One final test: test \r\n replacement when we're not in CRLF mode
+  {
+    RE re("b*", RE_Options(PCRE_NEWLINE_CR).set_utf8(support_utf8));
+    assert(re.error().empty());
+    string all("aa\r\naa\r\n");
+    CHECK(re.GlobalReplace("bb", &all) > 0);
+    CHECK_EQ(all, string("bbabbabb\rbb\nbbabbabb\rbb\nbb"));
+  }
+  {
+    RE re("b*", RE_Options(PCRE_NEWLINE_LF).set_utf8(support_utf8));
+    assert(re.error().empty());
+    string all("aa\r\naa\r\n");
+    CHECK(re.GlobalReplace("bb", &all) > 0);
+    CHECK_EQ(all, string("bbabbabb\rbb\nbbabbabb\rbb\nbb"));
+  }
+  // TODO: test what happens when no PCRE_NEWLINE_* flag is set.
+  //       Alas, the answer depends on how pcre was compiled.
 }
 
 static void TestExtract() {
index 3817203b5fda15915d8ff0ace8eb3dac43f3d277..8b06a9ce63191f7dd7cd3e3a4a3e03be03b6d99e 100644 (file)
@@ -117,7 +117,7 @@ if (rc < 0)
     */
     default: printf("Matching error %d\n", rc); break;
     }
-  free(re);     /* Release memory used for the compiled pattern */
+  pcre_free(re);     /* Release memory used for the compiled pattern */
   return 1;
   }
 
@@ -223,8 +223,8 @@ if (namecount <= 0) printf("No named substrings\n"); else
 
 if (!find_all)
   {
-  free(re);   /* Release the memory used for the compiled pattern */
-  return 0;   /* Finish unless -g was given */
+  pcre_free(re);   /* Release the memory used for the compiled pattern */
+  return 0;        /* Finish unless -g was given */
   }
 
 /* Loop for second and subsequent matches */
@@ -276,7 +276,7 @@ for (;;)
   if (rc < 0)
     {
     printf("Matching error %d\n", rc);
-    free(re);    /* Release memory used for the compiled pattern */
+    pcre_free(re);    /* Release memory used for the compiled pattern */
     return 1;
     }
 
@@ -317,7 +317,7 @@ for (;;)
   }      /* End of loop to find second and subsequent matches */
 
 printf("\n");
-free(re);       /* Release memory used for the compiled pattern */
+pcre_free(re);       /* Release memory used for the compiled pattern */
 return 0;
 }
 
index 1533c8366ae3a67dcd8f32328905f1fbadfff4cc..001588be2c6acf5d89f88b1e972bbc94c9657b68 100644 (file)
@@ -56,7 +56,7 @@ POSSIBILITY OF SUCH DAMAGE.
 
 typedef int BOOL;
 
-#define VERSION "4.2 09-Jan-2006"
+#define VERSION "4.3 01-Jun-2006"
 #define MAX_PATTERN_COUNT 100
 
 #if BUFSIZ > 8192
@@ -100,10 +100,14 @@ static const char *jfriedl_prefix = "";
 static const char *jfriedl_postfix = "";
 #endif
 
+static int  endlinebyte = '\n';     /* Last byte of endline sequence */
+static int  endlineextra = 0;       /* Extra bytes for endline sequence */
+
 static char *colour_string = (char *)"1;31";
 static char *colour_option = NULL;
 static char *dee_option = NULL;
 static char *DEE_option = NULL;
+static char *newline = NULL;
 static char *pattern_filename = NULL;
 static char *stdin_name = (char *)"(standard input)";
 static char *locale = NULL;
@@ -185,6 +189,7 @@ static option_item optionlist[] = {
   { OP_STRING,    N_LABEL,  &stdin_name,       "label=name",    "set name for standard input" },
   { OP_STRING,    N_LOCALE, &locale,           "locale=locale", "use the named locale" },
   { OP_NODATA,    'M',      NULL,              "multiline",     "run in multiline mode" },
+  { OP_STRING,    'N',      &newline,          "newline=type",  "specify newline type (CR, LR, CRLF)" },
   { OP_NODATA,    'n',      NULL,              "line-number",   "print line number with output lines" },
   { OP_NODATA,    'o',      NULL,              "only-matching", "show only the part of the line that matched" },
   { OP_NODATA,    'q',      NULL,              "quiet",         "suppress output, just set return code" },
@@ -493,8 +498,9 @@ if (after_context > 0 && lastmatchnumber > 0)
     char *pp = lastmatchrestart;
     if (printname != NULL) fprintf(stdout, "%s-", printname);
     if (number) fprintf(stdout, "%d-", lastmatchnumber++);
-    while (*pp != '\n') pp++;
-    fwrite(lastmatchrestart, 1, pp - lastmatchrestart + 1, stdout);
+    while (*pp != endlinebyte) pp++;
+    fwrite(lastmatchrestart, 1, pp - lastmatchrestart + (1 + endlineextra),
+      stdout);
     lastmatchrestart = pp + 1;
     }
   hyphenpending = TRUE;
@@ -566,7 +572,7 @@ while (ptr < endptr)
   that any match is constrained to be in the first line. */
 
   linelength = 0;
-  while (t < endptr && *t++ != '\n') linelength++;
+  while (t < endptr && *t++ != endlinebyte) linelength++;
   length = multiline? endptr - ptr : linelength;
 
 
@@ -705,7 +711,7 @@ while (ptr < endptr)
 
         while (p < ptr && linecount < after_context)
           {
-          while (*p != '\n') p++;
+          while (*p != endlinebyte) p++;
           p++;
           linecount++;
           }
@@ -719,8 +725,9 @@ while (ptr < endptr)
           char *pp = lastmatchrestart;
           if (printname != NULL) fprintf(stdout, "%s-", printname);
           if (number) fprintf(stdout, "%d-", lastmatchnumber++);
-          while (*pp != '\n') pp++;
-          fwrite(lastmatchrestart, 1, pp - lastmatchrestart + 1, stdout);
+          while (*pp != endlinebyte) pp++;
+          fwrite(lastmatchrestart, 1, pp - lastmatchrestart +
+            (1 + endlineextra), stdout);
           lastmatchrestart = pp + 1;
           }
         if (lastmatchrestart != ptr) hyphenpending = TRUE;
@@ -748,7 +755,7 @@ while (ptr < endptr)
           {
           linecount++;
           p--;
-          while (p > buffer && p[-1] != '\n') p--;
+          while (p > buffer && p[-1] != endlinebyte) p--;
           }
 
         if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted)
@@ -759,8 +766,8 @@ while (ptr < endptr)
           char *pp = p;
           if (printname != NULL) fprintf(stdout, "%s-", printname);
           if (number) fprintf(stdout, "%d-", linenumber - linecount--);
-          while (*pp != '\n') pp++;
-          fwrite(p, 1, pp - p + 1, stdout);   /* In case binary zero */
+          while (*pp != endlinebyte) pp++;
+          fwrite(p, 1, pp - p + (1 + endlineextra), stdout);
           p = pp + 1;
           }
         }
@@ -777,14 +784,14 @@ while (ptr < endptr)
       /* In multiline mode, we want to print to the end of the line in which
       the end of the matched string is found, so we adjust linelength and the
       line number appropriately. Because the PCRE_FIRSTLINE option is set, the
-      start of the match will always be before the first \n character. */
+      start of the match will always be before the first newline sequence. */
 
       if (multiline)
         {
         char *endmatch = ptr + offsets[1];
         t = ptr;
-        while (t < endmatch) { if (*t++ == '\n') linenumber++; }
-        while (endmatch < endptr && *endmatch != '\n') endmatch++;
+        while (t < endmatch) { if (*t++ == endlinebyte) linenumber++; }
+        while (endmatch < endptr && *endmatch != endlinebyte) endmatch++;
         linelength = endmatch - ptr;
         }
 
@@ -1206,7 +1213,7 @@ return FALSE;
 *************************************************/
 
 /* When the -F option has been used, each string may be a list of strings,
-separated by newlines. They will be matched literally.
+separated by line breaks. They will be matched literally.
 
 Arguments:
   pattern        the pattern string
@@ -1227,10 +1234,10 @@ if ((process_options & PO_FIXED_STRINGS) != 0)
   char buffer[MBUFTHIRD];
   for(;;)
     {
-    char *p = strchr(pattern, '\n');
+    char *p = strchr(pattern, endlinebyte);
     if (p == NULL)
       return compile_single_pattern(pattern, options, filename, count);
-    sprintf(buffer, "%.*s", p - pattern, pattern);
+    sprintf(buffer, "%.*s", p - pattern - endlineextra, pattern);
     pattern = p + 1;
     if (!compile_single_pattern(buffer, options, filename, count))
       return FALSE;
@@ -1260,6 +1267,16 @@ char *patterns[MAX_PATTERN_COUNT];
 const char *locale_from = "--locale";
 const char *error;
 
+/* Set the default line ending value from the default in the PCRE library. */
+
+(void)pcre_config(PCRE_CONFIG_NEWLINE, &i);
+switch(i)
+  {
+  default:                 newline = (char *)"lf"; break;
+  case '\r':               newline = (char *)"cr"; break;
+  case ('\r' << 8) | '\n': newline = (char *)"crlf"; break;
+  }
+
 /* Process the options */
 
 for (i = 1; i < argc; i++)
@@ -1543,6 +1560,28 @@ if (colour_option != NULL && strcmp(colour_option, "never") != 0)
     }
   }
 
+/* Interpret the newline type; the default settings are Unix-like. */
+
+if (strcmp(newline, "cr") == 0 || strcmp(newline, "CR") == 0)
+  {
+  pcre_options |= PCRE_NEWLINE_CR;
+  endlinebyte = '\r';
+  }
+else if (strcmp(newline, "lf") == 0 || strcmp(newline, "LF") == 0)
+  {
+  pcre_options |= PCRE_NEWLINE_LF;
+  }
+else if (strcmp(newline, "crlf") == 0 || strcmp(newline, "CRLF") == 0)
+  {
+  pcre_options |= PCRE_NEWLINE_CRLF;
+  endlineextra = 1;
+  }
+else
+  {
+  fprintf(stderr, "pcregrep: Invalid newline specifier \"%s\"\n", newline);
+  return 2;
+  }
+
 /* Interpret the text values for -d and -D */
 
 if (dee_option != NULL)
index cbb1ff800640a3930524f0f169fe890ea278a30b..b3472361c999cf488552e64b605ae2fb9f417725 100644 (file)
@@ -77,7 +77,7 @@ static const int eint[] = {
   REG_ASSERT,  /* internal error: code overflow */
   REG_BADPAT,  /* unrecognized character after (?< */
   REG_BADPAT,  /* lookbehind assertion is not fixed length */
-  REG_BADPAT,  /* malformed number after (?( */
+  REG_BADPAT,  /* malformed number or name after (?( */
   REG_BADPAT,  /* conditional group containe more than two branches */
   REG_BADPAT,  /* assertion expected after (?( */
   REG_BADPAT,  /* (?R or (?digits must be followed by ) */
@@ -94,11 +94,15 @@ static const int eint[] = {
   REG_BADPAT,  /* recursive call could loop indefinitely */
   REG_BADPAT,  /* unrecognized character after (?P */
   REG_BADPAT,  /* syntax error after (?P */
-  REG_BADPAT,  /* two named groups have the same name */
+  REG_BADPAT,  /* two named subpatterns have the same name */
   REG_BADPAT,  /* invalid UTF-8 string */
   REG_BADPAT,  /* support for \P, \p, and \X has not been compiled */
   REG_BADPAT,  /* malformed \P or \p sequence */
-  REG_BADPAT   /* unknown property name after \P or \p */
+  REG_BADPAT,  /* unknown property name after \P or \p */
+  REG_BADPAT,  /* subpattern name is too long (maximum 32 characters) */
+  REG_BADPAT,  /* too many named subpatterns (maximum 10,000) */
+  REG_BADPAT,  /* repeated subpattern is too long */
+  REG_BADPAT   /* octal value is greater than \377 (not in UTF-8 mode) */
 };
 
 /* Table of texts corresponding to POSIX error codes */
index f5c6cdd2e1d64fc3f15aa23ba6ec889b1f8eae3a..431378c6dc8c82ecbc4be0938e9984b3deca0ff0 100644 (file)
@@ -44,6 +44,10 @@ POSSIBILITY OF SUCH DAMAGE.
 #include <locale.h>
 #include <errno.h>
 
+#ifndef _WIN32
+#include <sys/resource.h>
+#endif
+
 #define PCRE_SPY        /* For Win32 build, import data, not export */
 
 /* We include pcre_internal.h because we need the internal info for displaying
@@ -101,11 +105,6 @@ function (define NOINFOCHECK). */
 
 #define LOOPREPEAT 500000
 
-#define BUFFER_SIZE 30000
-#define PBUFFER_SIZE BUFFER_SIZE
-#define DBUFFER_SIZE BUFFER_SIZE
-
-
 /* Static variables */
 
 static FILE *outfile;
@@ -119,10 +118,95 @@ static int show_malloc;
 static int use_utf8;
 static size_t gotten_store;
 
+/* The buffers grow automatically if very long input lines are encountered. */
+
+static int buffer_size = 50000;
+static uschar *buffer = NULL;
+static uschar *dbuffer = NULL;
 static uschar *pbuffer = NULL;
 
 
 
+/*************************************************
+*        Read or extend an input line            *
+*************************************************/
+
+/* Input lines are read into buffer, but both patterns and data lines can be
+continued over multiple input lines. In addition, if the buffer fills up, we
+want to automatically expand it so as to be able to handle extremely large
+lines that are needed for certain stress tests. When the input buffer is
+expanded, the other two buffers must also be expanded likewise, and the
+contents of pbuffer, which are a copy of the input for callouts, must be
+preserved (for when expansion happens for a data line). This is not the most
+optimal way of handling this, but hey, this is just a test program!
+
+Arguments:
+  f            the file to read
+  start        where in buffer to start (this *must* be within buffer)
+
+Returns:       pointer to the start of new data
+               could be a copy of start, or could be moved
+               NULL if no data read and EOF reached
+*/
+
+static uschar *
+extend_inputline(FILE *f, uschar *start)
+{
+uschar *here = start;
+
+for (;;)
+  {
+  int rlen = buffer_size - (here - buffer);
+  if (rlen > 1000)
+    {
+    int dlen;
+    if (fgets((char *)here, rlen,  f) == NULL)
+      return (here == start)? NULL : start;
+    dlen = (int)strlen((char *)here);
+    if (dlen > 0 && here[dlen - 1] == '\n') return start;
+    here += dlen;
+    }
+
+  else
+    {
+    int new_buffer_size = 2*buffer_size;
+    uschar *new_buffer = (unsigned char *)malloc(new_buffer_size);
+    uschar *new_dbuffer = (unsigned char *)malloc(new_buffer_size);
+    uschar *new_pbuffer = (unsigned char *)malloc(new_buffer_size);
+
+    if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)
+      {
+      fprintf(stderr, "pcretest: malloc(%d) failed\n", new_buffer_size);
+      exit(1);
+      }
+
+    memcpy(new_buffer, buffer, buffer_size);
+    memcpy(new_pbuffer, pbuffer, buffer_size);
+
+    buffer_size = new_buffer_size;
+
+    start = new_buffer + (start - buffer);
+    here = new_buffer + (here - buffer);
+
+    free(buffer);
+    free(dbuffer);
+    free(pbuffer);
+
+    buffer = new_buffer;
+    dbuffer = new_dbuffer;
+    pbuffer = new_pbuffer;
+    }
+  }
+
+return NULL;  /* Control never gets here */
+}
+
+
+
+
+
+
+
 /*************************************************
 *          Read number from string               *
 *************************************************/
@@ -159,19 +243,19 @@ return(result);
 and returns the value of the character.
 
 Argument:
-  buffer   a pointer to the byte vector
-  vptr     a pointer to an int to receive the value
+  utf8bytes   a pointer to the byte vector
+  vptr        a pointer to an int to receive the value
 
-Returns:   >  0 => the number of bytes consumed
-           -6 to 0 => malformed UTF-8 character at offset = (-return)
+Returns:      >  0 => the number of bytes consumed
+              -6 to 0 => malformed UTF-8 character at offset = (-return)
 */
 
 #if !defined NOUTF8
 
 static int
-utf82ord(unsigned char *buffer, int *vptr)
+utf82ord(unsigned char *utf8bytes, int *vptr)
 {
-int c = *buffer++;
+int c = *utf8bytes++;
 int d = c;
 int i, j, s;
 
@@ -191,7 +275,7 @@ d = (c & utf8_table3[i]) << s;
 
 for (j = 0; j < i; j++)
   {
-  c = *buffer++;
+  c = *utf8bytes++;
   if ((c & 0xc0) != 0x80) return -(j+1);
   s -= 6;
   d |= (c & 0x3f) << s;
@@ -222,24 +306,24 @@ 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
+  utf8bytes  pointer to buffer for result - at least 6 bytes long
 
 Returns:     number of characters placed in the buffer
 */
 
 static int
-ord2utf8(int cvalue, uschar *buffer)
+ord2utf8(int cvalue, uschar *utf8bytes)
 {
 register int i, j;
 for (i = 0; i < utf8_table1_size; i++)
   if (cvalue <= utf8_table1[i]) break;
-buffer += i;
+utf8bytes += i;
 for (j = i; j > 0; j--)
  {
- *buffer-- = 0x80 | (cvalue & 0x3f);
+ *utf8bytes-- = 0x80 | (cvalue & 0x3f);
  cvalue >>= 6;
  }
-*buffer = utf8_table2[i] | cvalue;
+*utf8bytes = utf8_table2[i] | cvalue;
 return i + 1;
 }
 
@@ -461,8 +545,8 @@ if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0)
 *         Byte flipping function                 *
 *************************************************/
 
-static long int
-byteflip(long int value, int n)
+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) |
@@ -525,6 +609,32 @@ return count;
 
 
 
+/*************************************************
+*         Check newline indicator                *
+*************************************************/
+
+/* This is used both at compile and run-time to check for <xxx> escapes, where
+xxx is LF, CR, or CRLF. Print a message and return 0 if there is no match.
+
+Arguments:
+  p           points after the leading '<'
+  f           file for error message
+
+Returns:      appropriate PCRE_NEWLINE_xxx flags, or 0
+*/
+
+static int
+check_newline(uschar *p, FILE *f)
+{
+if (strncmp((char *)p, "cr>", 3) == 0) return PCRE_NEWLINE_CR;
+if (strncmp((char *)p, "lf>", 3) == 0) return PCRE_NEWLINE_LF;
+if (strncmp((char *)p, "crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;
+fprintf(f, "Unknown newline type at: <%s\n", p);
+return 0;
+}
+
+
+
 /*************************************************
 *                Main Program                    *
 *************************************************/
@@ -553,16 +663,23 @@ int debug = 0;
 int done = 0;
 int all_use_dfa = 0;
 int yield = 0;
+int stack_size;
 
-unsigned char *buffer;
-unsigned char *dbuffer;
+/* These vectors store, end-to-end, a list of captured substring names. Assume
+that 1024 is plenty long enough for the few names we'll be testing. */
+
+uschar copynames[1024];
+uschar getnames[1024];
+
+uschar *copynamesptr;
+uschar *getnamesptr;
 
 /* Get buffers from malloc() so that Electric Fence will check their misuse
-when I am debugging. */
+when I am debugging. They grow automatically when very long lines are read. */
 
-buffer = (unsigned char *)malloc(BUFFER_SIZE);
-dbuffer = (unsigned char *)malloc(DBUFFER_SIZE);
-pbuffer = (unsigned char *)malloc(PBUFFER_SIZE);
+buffer = (unsigned char *)malloc(buffer_size);
+dbuffer = (unsigned char *)malloc(buffer_size);
+pbuffer = (unsigned char *)malloc(buffer_size);
 
 /* The outfile variable is static so that new_malloc can use it. The _setmode()
 stuff is some magic that I don't understand, but which apparently does good
@@ -596,6 +713,28 @@ while (argc > 1 && argv[op][0] == '-')
     op++;
     argc--;
     }
+  else if (strcmp(argv[op], "-S") == 0 && argc > 2 &&
+      ((stack_size = get_value((unsigned char *)argv[op+1], &endptr)),
+        *endptr == 0))
+    {
+#ifdef _WIN32
+    printf("PCRE: -S not supported on this OS\n");
+    exit(1);
+#else
+    int rc;
+    struct rlimit rlim;
+    getrlimit(RLIMIT_STACK, &rlim);
+    rlim.rlim_cur = stack_size * 1024 * 1024;
+    rc = setrlimit(RLIMIT_STACK, &rlim);
+    if (rc != 0)
+      {
+    printf("PCRE: setrlimit() failed with error %d\n", rc);
+    exit(1);
+      }
+    op++;
+    argc--;
+#endif
+    }
 #if !defined NOPOSIX
   else if (strcmp(argv[op], "-p") == 0) posix = 1;
 #endif
@@ -609,7 +748,8 @@ while (argc > 1 && argv[op][0] == '-')
     (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);
     printf("  %sUnicode properties support\n", rc? "" : "No ");
     (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);
-    printf("  Newline character is %s\n", (rc == '\r')? "CR" : "LF");
+    printf("  Newline sequence is %s\n", (rc == '\r')? "CR" :
+      (rc == '\n')? "LF" : "CRLF");
     (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc);
     printf("  Internal link size = %d\n", rc);
     (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc);
@@ -625,7 +765,7 @@ while (argc > 1 && argv[op][0] == '-')
   else
     {
     printf("** Unknown or malformed option %s\n", argv[op]);
-    printf("Usage:   pcretest [-d] [-i] [-o <n>] [-p] [-s] [-t] [<input> [<output>]]\n");
+    printf("Usage:   pcretest [options] [<input> [<output>]]\n");
     printf("  -C     show PCRE compile-time options and exit\n");
     printf("  -d     debug: show compiled code; implies -i\n");
 #if !defined NODFA
@@ -637,6 +777,7 @@ while (argc > 1 && argv[op][0] == '-')
 #if !defined NOPOSIX
     printf("  -p     use POSIX interface\n");
 #endif
+    printf("  -S <n> set stack size to <n> megabytes\n");
     printf("  -s     output store (memory) used information\n"
            "  -t     time compilation and execution\n");
     yield = 1;
@@ -723,7 +864,7 @@ while (!done)
   use_utf8 = 0;
 
   if (infile == stdin) printf("  re> ");
-  if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) break;
+  if (extend_inputline(infile, buffer) == NULL) break;
   if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
   fflush(outfile);
 
@@ -735,7 +876,7 @@ while (!done)
 
   if (*p == '<' && strchr((char *)(p+1), '<') == NULL)
     {
-    unsigned long int magic;
+    unsigned long int magic, get_options;
     uschar sbuf[8];
     FILE *f;
 
@@ -783,8 +924,8 @@ while (!done)
 
     /* Need to know if UTF-8 for printing data strings */
 
-    new_info(re, NULL, PCRE_INFO_OPTIONS, &options);
-    use_utf8 = (options & PCRE_UTF8) != 0;
+    new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
+    use_utf8 = (get_options & PCRE_UTF8) != 0;
 
     /* Now see if there is any following study data */
 
@@ -838,16 +979,8 @@ while (!done)
       pp++;
       }
     if (*pp != 0) break;
-
-    len = BUFFER_SIZE - (pp - buffer);
-    if (len < 256)
-      {
-      fprintf(outfile, "** Expression too long - missing delimiter?\n");
-      goto SKIP_DATA;
-      }
-
     if (infile == stdin) printf("    > ");
-    if (fgets((char *)pp, len, infile) == NULL)
+    if ((pp = extend_inputline(infile, pp)) == NULL)
       {
       fprintf(outfile, "** Unexpected EOF\n");
       done = 1;
@@ -893,6 +1026,7 @@ while (!done)
       case 'F': do_flip = 1; break;
       case 'G': do_G = 1; break;
       case 'I': do_showinfo = 1; break;
+      case 'J': options |= PCRE_DUPNAMES; break;
       case 'M': log_store = 1; break;
       case 'N': options |= PCRE_NO_AUTO_CAPTURE; break;
 
@@ -927,6 +1061,15 @@ while (!done)
       *pp = 0;
       break;
 
+      case '<':
+        {
+        int x = check_newline(pp, outfile);
+        if (x == 0) goto SKIP_DATA;
+        options |= x;
+        while (*pp++ != '>');
+        }
+      break;
+
       case '\r':                      /* So that it works in Windows */
       case '\n':
       case ' ':
@@ -961,7 +1104,7 @@ while (!done)
 
     if (rc != 0)
       {
-      (void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE);
+      (void)regerror(rc, &preg, (char *)buffer, buffer_size);
       fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer);
       goto SKIP_DATA;
       }
@@ -1002,7 +1145,7 @@ while (!done)
         {
         for (;;)
           {
-          if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL)
+          if (extend_inputline(infile, buffer) == NULL)
             {
             done = 1;
             goto CONTINUE;
@@ -1163,13 +1306,13 @@ while (!done)
       if (do_flip)
         {
         all_options = byteflip(all_options, sizeof(all_options));
-        }
+         }
 
       if ((all_options & PCRE_NOPARTIAL) != 0)
         fprintf(outfile, "Partial matching not supported\n");
 
       if (get_options == 0) fprintf(outfile, "No options\n");
-        else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s%s%s\n",
+        else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
           ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",
           ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",
           ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",
@@ -1181,14 +1324,30 @@ while (!done)
           ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",
           ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",
           ((get_options & PCRE_UTF8) != 0)? " utf8" : "",
-          ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "");
+          ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "",
+          ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");
+
+      switch (get_options & PCRE_NEWLINE_CRLF)
+        {
+        case PCRE_NEWLINE_CR:
+        fprintf(outfile, "Forced newline sequence: CR\n");
+        break;
+
+        case PCRE_NEWLINE_LF:
+        fprintf(outfile, "Forced newline sequence: LF\n");
+        break;
 
-      if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0)
-        fprintf(outfile, "Case state changes\n");
+        case PCRE_NEWLINE_CRLF:
+        fprintf(outfile, "Forced newline sequence: CRLF\n");
+        break;
+
+        default:
+        break;
+        }
 
       if (first_char == -1)
         {
-        fprintf(outfile, "First char at start or follows \\n\n");
+        fprintf(outfile, "First char at start or follows newline\n");
         }
       else if (first_char < 0)
         {
@@ -1343,6 +1502,12 @@ while (!done)
 
     options = 0;
 
+    *copynames = 0;
+    *getnames = 0;
+
+    copynamesptr = copynames;
+    getnamesptr = getnames;
+
     pcre_callout = callout;
     first_callout = 1;
     callout_extra = 0;
@@ -1351,15 +1516,24 @@ while (!done)
     callout_fail_id = -1;
     show_malloc = 0;
 
-    if (infile == stdin) printf("data> ");
-    if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL)
+    if (extra != NULL) extra->flags &=
+      ~(PCRE_EXTRA_MATCH_LIMIT|PCRE_EXTRA_MATCH_LIMIT_RECURSION);
+
+    len = 0;
+    for (;;)
       {
-      done = 1;
-      goto CONTINUE;
+      if (infile == stdin) printf("data> ");
+      if (extend_inputline(infile, buffer + len) == NULL)
+        {
+        if (len > 0) break;
+        done = 1;
+        goto CONTINUE;
+        }
+      if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
+      len = (int)strlen((char *)buffer);
+      if (buffer[len-1] == '\n') break;
       }
-    if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
 
-    len = (int)strlen((char *)buffer);
     while (len > 0 && isspace(buffer[len-1])) len--;
     buffer[len] = 0;
     if (len == 0) break;
@@ -1389,6 +1563,17 @@ while (!done)
         c -= '0';
         while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9')
           c = c * 8 + *p++ - '0';
+
+#if !defined NOUTF8
+        if (use_utf8 && c > 255)
+          {
+          unsigned char buff8[8];
+          int ii, utn;
+          utn = ord2utf8(c, buff8);
+          for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
+          c = buff8[ii];   /* Last byte */
+          }
+#endif
         break;
 
         case 'x':
@@ -1450,14 +1635,14 @@ while (!done)
           }
         else if (isalnum(*p))
           {
-          uschar name[256];
-          uschar *npp = name;
+          uschar *npp = copynamesptr;
           while (isalnum(*p)) *npp++ = *p++;
+          *npp++ = 0;
           *npp = 0;
-          n = pcre_get_stringnumber(re, (char *)name);
+          n = pcre_get_stringnumber(re, (char *)copynamesptr);
           if (n < 0)
-            fprintf(outfile, "no parentheses with name \"%s\"\n", name);
-          else copystrings |= 1 << n;
+            fprintf(outfile, "no parentheses with name \"%s\"\n", copynamesptr);
+          copynamesptr = npp;
           }
         else if (*p == '+')
           {
@@ -1518,14 +1703,14 @@ while (!done)
           }
         else if (isalnum(*p))
           {
-          uschar name[256];
-          uschar *npp = name;
+          uschar *npp = getnamesptr;
           while (isalnum(*p)) *npp++ = *p++;
+          *npp++ = 0;
           *npp = 0;
-          n = pcre_get_stringnumber(re, (char *)name);
+          n = pcre_get_stringnumber(re, (char *)getnamesptr);
           if (n < 0)
-            fprintf(outfile, "no parentheses with name \"%s\"\n", name);
-          else getstrings |= 1 << n;
+            fprintf(outfile, "no parentheses with name \"%s\"\n", getnamesptr);
+          getnamesptr = npp;
           }
         continue;
 
@@ -1564,6 +1749,28 @@ while (!done)
         options |= PCRE_PARTIAL;
         continue;
 
+        case 'Q':
+        while(isdigit(*p)) n = n * 10 + *p++ - '0';
+        if (extra == NULL)
+          {
+          extra = (pcre_extra *)malloc(sizeof(pcre_extra));
+          extra->flags = 0;
+          }
+        extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
+        extra->match_limit_recursion = n;
+        continue;
+
+        case 'q':
+        while(isdigit(*p)) n = n * 10 + *p++ - '0';
+        if (extra == NULL)
+          {
+          extra = (pcre_extra *)malloc(sizeof(pcre_extra));
+          extra->flags = 0;
+          }
+        extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
+        extra->match_limit = n;
+        continue;
+
 #if !defined NODFA
         case 'R':
         options |= PCRE_DFA_RESTART;
@@ -1581,6 +1788,15 @@ while (!done)
         case '?':
         options |= PCRE_NO_UTF8_CHECK;
         continue;
+
+        case '<':
+          {
+          int x = check_newline(p, outfile);
+          if (x == 0) goto NEXT_DATA;
+          options |= x;
+          while (*p++ != '>');
+          }
+        continue;
         }
       *q++ = c;
       }
@@ -1611,7 +1827,7 @@ while (!done)
 
       if (rc != 0)
         {
-        (void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE);
+        (void)regerror(rc, &preg, (char *)buffer, buffer_size);
         fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer);
         }
       else if ((((const pcre *)preg.re_pcre)->options & PCRE_NO_AUTO_CAPTURE)
@@ -1690,7 +1906,7 @@ while (!done)
           extra->flags = 0;
           }
 
-        count = check_match_limit(re, extra, bptr, len, start_offset,
+        (void)check_match_limit(re, extra, bptr, len, start_offset,
           options|g_notempty, use_offsets, use_size_offsets,
           PCRE_EXTRA_MATCH_LIMIT, &(extra->match_limit),
           PCRE_ERROR_MATCHLIMIT, "match()");
@@ -1778,7 +1994,7 @@ while (!done)
           {
           if ((copystrings & (1 << i)) != 0)
             {
-            char copybuffer[16];
+            char copybuffer[256];
             int rc = pcre_copy_substring((char *)bptr, use_offsets, count,
               i, copybuffer, sizeof(copybuffer));
             if (rc < 0)
@@ -1788,6 +2004,19 @@ while (!done)
             }
           }
 
+        for (copynamesptr = copynames;
+             *copynamesptr != 0;
+             copynamesptr += (int)strlen((char*)copynamesptr) + 1)
+          {
+          char copybuffer[256];
+          int rc = pcre_copy_named_substring(re, (char *)bptr, use_offsets,
+            count, (char *)copynamesptr, copybuffer, sizeof(copybuffer));
+          if (rc < 0)
+            fprintf(outfile, "copy substring %s failed %d\n", copynamesptr, rc);
+          else
+            fprintf(outfile, "  C %s (%d) %s\n", copybuffer, rc, copynamesptr);
+          }
+
         for (i = 0; i < 32; i++)
           {
           if ((getstrings & (1 << i)) != 0)
@@ -1800,12 +2029,27 @@ while (!done)
             else
               {
               fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc);
-              /* free((void *)substring); */
               pcre_free_substring(substring);
               }
             }
           }
 
+        for (getnamesptr = getnames;
+             *getnamesptr != 0;
+             getnamesptr += (int)strlen((char*)getnamesptr) + 1)
+          {
+          const char *substring;
+          int rc = pcre_get_named_substring(re, (char *)bptr, use_offsets,
+            count, (char *)getnamesptr, &substring);
+          if (rc < 0)
+            fprintf(outfile, "copy substring %s failed %d\n", getnamesptr, rc);
+          else
+            {
+            fprintf(outfile, "  G %s (%d) %s\n", substring, rc, getnamesptr);
+            pcre_free_substring(substring);
+            }
+          }
+
         if (getlist)
           {
           const char **stringlist;
@@ -1905,6 +2149,8 @@ while (!done)
         len -= use_offsets[1];
         }
       }  /* End of loop for /g and /G */
+
+    NEXT_DATA: continue;
     }    /* End of loop for data lines */
 
   CONTINUE:
index aebba027703a733c5e8b5068a8ffb38abd5df979..4c02567552eb389da34b35eeff9c26fb9878b938 100644 (file)
@@ -39,4 +39,11 @@ eighteen
 nineteen
 twenty
 
+Here follows some CR/LF/CRLF test data.
+
+abc
+def
+ghi
+jkl
+
 This is the last line of this file.
index 88ff5bf8e7dde2c4fe60e7c7c0c80c69f5e96195..6cb400bd7009aed6822bf8d052b2802650a1bed3 100644 (file)
 /(abc)\323/
     abc\xd3
 
-/(abc)\500/
+/(abc)\100/
     abc\x40
     abc\100
 
-/(abc)\5000/
+/(abc)\1000/
     abc\x400
     abc\x40\x30
     abc\1000
     ** Failers 
     abcddefg
 
+/(?<![^f]oo)(bar)/
+    foobarX 
+    ** Failers 
+    boobarX
+
+/(?<![^f])X/
+    offX
+    ** Failers
+    onyX  
+
+/(?<=[^f])X/
+    onyX
+    ** Failers
+    offX 
+
+/^/mg
+    a\nb\nc\n
+    \ 
+    
+/(?<=C\n)^/mg
+    A\nC\nC\n 
+
+/(?:(?(1)a|b)(X))+/
+    bXaX
+
+/(?:(?(1)\1a|b)(X|Y))+/
+    bXXaYYaY
+    bXYaXXaX  
+
+/()()()()()()()()()(?:(?(10)\10a|b)(X|Y))+/
+    bXXaYYaY
+
+/[[,abc,]+]/
+    abc]
+    a,b]
+    [a,b,c]  
+
 / End of testinput1 /
index 60d2db00f1e6d4b0ed98ef921bd9d8424d309d0b..0a87466ae7ca5a1dd1cc502c08f073cf617c4612 100644 (file)
     Ab
     AB        
 
-/[\200-\410]/
+/[\200-\110]/
 
 /^(?(0)f|b)oo/
 
 
 /\x{0000ff}/
 
+/^((?P<A>a1)|(?P<A>a2)b)/
+
+/^((?P<A>a1)|(?P<A>a2)b)/J
+    a1b\CA
+    a2b\CA 
+    ** Failers
+    a1b\CZ\CA 
+    
+/^(?P<A>a)(?P<A>b)/J
+    ab\CA
+    
+/^(?P<A>a)(?P<A>b)|cd/J
+    ab\CA
+    cd\CA 
+  
+/^(?P<A>a)(?P<A>b)|cd(?P<A>ef)(?P<A>gh)/J
+    cdefgh\CA 
+  
+/^((?P<A>a1)|(?P<A>a2)b)/J
+    a1b\GA
+    a2b\GA 
+    ** Failers
+    a1b\GZ\GA 
+    
+/^(?P<A>a)(?P<A>b)/J
+    ab\GA
+    
+/^(?P<A>a)(?P<A>b)|cd/J
+    ab\GA
+    cd\GA 
+  
+/^(?P<A>a)(?P<A>b)|cd(?P<A>ef)(?P<A>gh)/J
+    cdefgh\GA 
+  
+/(?J)^((?P<A>a1)|(?P<A>a2)b)/
+    a1b\CA
+    a2b\CA 
+    
+/^(?P<A>a) (?J:(?P<B>b)(?P<B>c)) (?P<A>d)/
+
+/ In this next test, J is not set at the outer level; consequently it isn't
+set in the pattern's options; consequently pcre_get_named_substring() produces 
+a random value. /x
+
+/^(?P<A>a) (?J:(?P<B>b)(?P<B>c)) (?P<C>d)/
+    a bc d\CA\CB\CC
+
+/^(?P<A>a)?(?(A)a|b)/
+    aabc
+    bc
+    ** Failers
+    abc   
+
+/(?:(?(ZZ)a|b)(?P<ZZ>X))+/
+    bXaX
+
+/(?:(?(2y)a|b)(X))+/
+
+/(?:(?(ZA)a|b)(?P<ZZ>X))+/
+
+/(?:(?(ZZ)a|b)(?(ZZ)a|b)(?P<ZZ>X))+/
+    bbXaaX
+
+/(?:(?(ZZ)a|\(b\))\\(?P<ZZ>X))+/
+    (b)\\Xa\\X
+
+/(?P<ABC/
+
+/(?:(?(A)(?P=A)a|b)(?P<A>X|Y))+/
+    bXXaYYaY
+    bXYaXXaX  
+
+/()()()()()()()()()(?:(?(A)(?P=A)a|b)(?P<A>X|Y))+/
+    bXXaYYaY
+
+/\777/
+
+/\s*,\s*/S
+    \x0b,\x0b
+    \x0c,\x0d 
+
+/^abc/m
+    xyz\nabc
+    xyz\nabc\<lf>
+    xyz\r\nabc\<lf>
+    xyz\rabc\<cr>
+    xyz\r\nabc\<crlf>
+    ** Failers 
+    xyz\nabc\<cr>
+    xyz\r\nabc\<cr>
+    xyz\nabc\<crlf>
+    xyz\rabc\<crlf>
+    xyz\rabc\<lf>
+    
+/abc$/m
+    xyzabc
+    xyzabc\n 
+    xyzabc\npqr 
+    xyzabc\r\<cr> 
+    xyzabc\rpqr\<cr> 
+    xyzabc\r\n\<crlf> 
+    xyzabc\r\npqr\<crlf> 
+    ** Failers
+    xyzabc\r 
+    xyzabc\rpqr 
+    xyzabc\r\n 
+    xyzabc\r\npqr 
+    
+/^abc/m<cr>
+    xyz\rabcdef
+    xyz\nabcdef\<lf>
+    ** Failers  
+    xyz\nabcdef
+       
+/^abc/m<lf>
+    xyz\nabcdef
+    xyz\rabcdef\<cr>
+    ** Failers  
+    xyz\rabcdef
+       
+/^abc/m<crlf>
+    xyz\r\nabcdef
+    xyz\rabcdef\<cr>
+    ** Failers  
+    xyz\rabcdef
+    
+/^abc/m<bad>
+
+/abc/
+    xyz\rabc\<bad>
+    abc  
+       
+/.*/
+    abc\ndef
+    abc\rdef
+    abc\r\ndef
+    \<cr>abc\ndef
+    \<cr>abc\rdef
+    \<cr>abc\r\ndef
+    \<crlf>abc\ndef
+    \<crlf>abc\rdef
+    \<crlf>abc\r\ndef
+
+/\w+(.)(.)?def/s
+    abc\ndef
+    abc\rdef
+    abc\r\ndef
+
++((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)+
+   /* this is a C style comment */\M
+
+/(?P<B>25[0-5]|2[0-4]\d|[01]?\d?\d)(?:\.(?P>B)){3}/
+
 / End of testinput2 /
index 6e0099c649006c31148e0df05961a200702dbec2..9ff0fc7a647e66e9e78693ab8f5b7f13fa9915b5 100644 (file)
 /^\x{85}$/8i
     \x{85}
 
+/^ሴ/8
+    ሴ 
+
 /^\ሴ/8
     ሴ 
 
+"(?s)(.{1,5})"8
+    abcdefg
+    ab
+
 / End of testinput4 /
index dc45445f68334fc566a25f988ec905fd3714e19c..54643f6516815330cbf776be93ed2690099e3443 100644 (file)
 
 /^\ሴ/8D
 
+/\777/I
+
+/\777/8I
+  \x{1ff}
+  \777 
+
 / End of testinput5 /
index a45920a17e7923da7e2191ea59fb6984a164c884..da5b9ca23627395cd40842f3bea7b98f541645ea 100644 (file)
      \x{1c5}XY
      AXY      
 
+/^(\p{Z}[^\p{C}\p{Z}]+)*$/
+    \xa0!
+
+/^[\pL](abc)(?1)/
+    AabcabcYZ    
+
+/([\pL]=(abc))*X/
+    L=abcX
+
 / End of testinput6 /
index 309ed3f008ce46f17dc822e11b355034294075d2..8e2d7c3ba0a9c06b27f166779aad703fe7168d67 100644 (file)
 /(abc)\323/
     abc\xd3
 
-/(abc)\500/
+/(abc)\100/
     abc\x40
     abc\100
 
-/(abc)\5000/
+/(abc)\1000/
     abc\x400
     abc\x40\x30
     abc\1000
     123\P
     4\P\R
 
+/^/mg
+    a\nb\nc\n
+    \ 
+    
+/(?<=C\n)^/mg
+    A\nC\nC\n 
+
+/(?s)A?B/
+    AB
+    aB  
+
+/(?s)A*B/
+    AB
+    aB  
+
+/(?m)A?B/
+    AB
+    aB  
+
+/(?m)A*B/
+    AB
+    aB  
+
+/Content-Type\x3A[^\r\n]{6,}/
+    Content-Type:xxxxxyyy 
+
+/Content-Type\x3A[^\r\n]{6,}z/
+    Content-Type:xxxxxyyyz
+
+/Content-Type\x3A[^a]{6,}/
+    Content-Type:xxxyyy 
+
+/Content-Type\x3A[^a]{6,}z/
+    Content-Type:xxxyyyz
+
+/^abc/m
+    xyz\nabc
+    xyz\nabc\<lf>
+    xyz\r\nabc\<lf>
+    xyz\rabc\<cr>
+    xyz\r\nabc\<crlf>
+    ** Failers 
+    xyz\nabc\<cr>
+    xyz\r\nabc\<cr>
+    xyz\nabc\<crlf>
+    xyz\rabc\<crlf>
+    xyz\rabc\<lf>
+    
+/abc$/m
+    xyzabc
+    xyzabc\n 
+    xyzabc\npqr 
+    xyzabc\r\<cr> 
+    xyzabc\rpqr\<cr> 
+    xyzabc\r\n\<crlf> 
+    xyzabc\r\npqr\<crlf> 
+    ** Failers
+    xyzabc\r 
+    xyzabc\rpqr 
+    xyzabc\r\n 
+    xyzabc\r\npqr 
+    
+/^abc/m<cr>
+    xyz\rabcdef
+    xyz\nabcdef\<lf>
+    ** Failers  
+    xyz\nabcdef
+       
+/^abc/m<lf>
+    xyz\nabcdef
+    xyz\rabcdef\<cr>
+    ** Failers  
+    xyz\rabcdef
+       
+/^abc/m<crlf>
+    xyz\r\nabcdef
+    xyz\rabcdef\<cr>
+    ** Failers  
+    xyz\rabcdef
+    
+/.*/
+    abc\ndef
+    abc\rdef
+    abc\r\ndef
+    \<cr>abc\ndef
+    \<cr>abc\rdef
+    \<cr>abc\r\ndef
+    \<crlf>abc\ndef
+    \<crlf>abc\rdef
+    \<crlf>abc\r\ndef
+
+/\w+(.)(.)?def/s
+    abc\ndef
+    abc\rdef
+    abc\r\ndef
+
 / End of testinput7 /
index f3e5da3d568cafb3a894527983187f407c427a08..6f5ae19b9f0c5ad1f41c2ce127e180123723efd6 100644 (file)
@@ -2127,7 +2127,7 @@ No match
  0: abc\xd3
  1: abc
 
-/(abc)\500/
+/(abc)\100/
     abc\x40
  0: abc@
  1: abc
@@ -2135,7 +2135,7 @@ No match
  0: abc@
  1: abc
 
-/(abc)\5000/
+/(abc)\1000/
     abc\x400
  0: abc@0
  1: abc
@@ -6282,4 +6282,76 @@ No match
     abcddefg
 No match
 
+/(?<![^f]oo)(bar)/
+    foobarX 
+ 0: bar
+ 1: bar
+    ** Failers 
+No match
+    boobarX
+No match
+
+/(?<![^f])X/
+    offX
+ 0: X
+    ** Failers
+No match
+    onyX  
+No match
+
+/(?<=[^f])X/
+    onyX
+ 0: X
+    ** Failers
+No match
+    offX 
+No match
+
+/^/mg
+    a\nb\nc\n
+ 0: 
+ 0: 
+ 0: 
+    \ 
+ 0: 
+    
+/(?<=C\n)^/mg
+    A\nC\nC\n 
+ 0: 
+
+/(?:(?(1)a|b)(X))+/
+    bXaX
+ 0: bXaX
+ 1: X
+
+/(?:(?(1)\1a|b)(X|Y))+/
+    bXXaYYaY
+ 0: bXXaYYaY
+ 1: Y
+    bXYaXXaX  
+ 0: bX
+ 1: X
+
+/()()()()()()()()()(?:(?(10)\10a|b)(X|Y))+/
+    bXXaYYaY
+ 0: bX
+ 1: 
+ 2: 
+ 3: 
+ 4: 
+ 5: 
+ 6: 
+ 7: 
+ 8: 
+ 9: 
+10: X
+
+/[[,abc,]+]/
+    abc]
+ 0: abc]
+    a,b]
+ 0: a,b]
+    [a,b,c]  
+ 0: [a,b,c]
+
 / End of testinput1 /
index 55adba0b9d7baa64945e2bc03f119b71fc810e5b..bcde708569e26a4d716d67f7f9a31d9176a41800 100644 (file)
@@ -115,14 +115,14 @@ Failed: unrecognized character after (? at offset 2
 Capturing subpattern count = 0
 Partial matching not supported
 No options
-First char at start or follows \n
+First char at start or follows newline
 Need char = 'b'
 
 /.*?b/
 Capturing subpattern count = 0
 Partial matching not supported
 No options
-First char at start or follows \n
+First char at start or follows newline
 Need char = 'b'
 
 /cat|dog|elephant/
@@ -326,7 +326,7 @@ No need char
 Capturing subpattern count = 3
 Partial matching not supported
 No options
-First char at start or follows \n
+First char at start or follows newline
 No need char
     defabc
  0: defabc
@@ -517,7 +517,6 @@ No need char
 /(^b|(?i)^d)/
 Capturing subpattern count = 1
 Options: anchored
-Case state changes
 No first char
 No need char
 
@@ -552,13 +551,13 @@ Starting byte set: b c x y
 /(^a|^b)/m
 Capturing subpattern count = 1
 Options: multiline
-First char at start or follows \n
+First char at start or follows newline
 No need char
 
 /(?i)(^a|^b)/m
 Capturing subpattern count = 1
 Options: caseless multiline
-First char at start or follows \n
+First char at start or follows newline
 No need char
 
 /(a)(?(1)a|b|c)/
@@ -568,13 +567,13 @@ Failed: conditional group contains more than two branches at offset 13
 Failed: conditional group contains more than two branches at offset 12
 
 /(?(1a)/
-Failed: malformed number after (?( at offset 4
+Failed: reference to non-existent subpattern at offset 6
 
 /(?(?i))/
 Failed: assertion expected after (?( at offset 3
 
 /(?(abc))/
-Failed: assertion expected after (?( at offset 3
+Failed: reference to non-existent subpattern at offset 7
 
 /(?(?<ab))/
 Failed: unrecognized character after (?< at offset 5
@@ -592,7 +591,6 @@ Capturing subpattern count = 1
 Max back reference = 1
 Partial matching not supported
 No options
-Case state changes
 First char = 'b' (caseless)
 Need char = 'h' (caseless)
 
@@ -609,7 +607,6 @@ Need char = 'h' (caseless)
 ------------------------------------------------------------------
 Capturing subpattern count = 1
 No options
-Case state changes
 First char = 'b' (caseless)
 No need char
 Study returned NULL
@@ -618,7 +615,6 @@ Study returned NULL
 Capturing subpattern count = 1
 Partial matching not supported
 No options
-Case state changes
 No first char
 No need char
 Starting byte set: C a b c d 
@@ -664,7 +660,7 @@ No need char
 /^abc/m 
 Capturing subpattern count = 0
 Options: multiline
-First char at start or follows \n
+First char at start or follows newline
 Need char = 'c'
 
 /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/
@@ -721,7 +717,7 @@ No match
 /^(?<=foo\n)bar/m
 Capturing subpattern count = 0
 Options: multiline
-First char at start or follows \n
+First char at start or follows newline
 Need char = 'r'
     foo\nbarbar 
  0: bar
@@ -737,7 +733,7 @@ No match
 /(?>^abc)/m
 Capturing subpattern count = 0
 Options: multiline
-First char at start or follows \n
+First char at start or follows newline
 Need char = 'c'
     abc
  0: abc
@@ -782,7 +778,6 @@ No match
 /(?<=ab(?i)x|y|z)/
 Capturing subpattern count = 0
 No options
-Case state changes
 No first char
 No need char
 
@@ -790,7 +785,7 @@ No need char
 Capturing subpattern count = 2
 Partial matching not supported
 No options
-First char at start or follows \n
+First char at start or follows newline
 No need char
     alphabetabcd
  0: alphabetabcd
@@ -803,7 +798,6 @@ No need char
 /(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/
 Capturing subpattern count = 0
 No options
-Case state changes
 First char = 'Z'
 Need char = 'Z'
     abxyZZ
@@ -966,7 +960,7 @@ Failed: unrecognized character after (? at offset 3
 Failed: unrecognized character after (? at offset 3
 
 /(?(1?)a|b)/
-Failed: malformed number after (?( at offset 4
+Failed: malformed number or name after (?( at offset 4
 
 /(?(1)a|b|c)/
 Failed: conditional group contains more than two branches at offset 10
@@ -1021,7 +1015,7 @@ No need char
     abcdefghijklmnopqrstuvwxyz\C1
  0: abcdefghijklmnopqrst
  1: abcdefghijklmnopqrst
-copy substring 1 failed -6
+ 1C abcdefghijklmnopqrst (20)
     abcdefghijklmnopqrstuvwxyz\G1
  0: abcdefghijklmnopqrst
  1: abcdefghijklmnopqrst
@@ -1054,7 +1048,7 @@ No need char
     abcdefghijklmnopqrstuvwxyz\C1\G1\L
  0: abcdefghijklmnop
  1: abcdefghijklmnop
-copy substring 1 failed -6
+ 1C abcdefghijklmnop (16)
  1G abcdefghijklmnop (16)
  0L abcdefghijklmnop
  1L abcdefghijklmnop
@@ -1128,7 +1122,7 @@ Need char = 'd'
 Capturing subpattern count = 0
 Partial matching not supported
 No options
-First char at start or follows \n
+First char at start or follows newline
 Need char = 'X'
 
 /.*X/Ds
@@ -1161,7 +1155,7 @@ Need char = 'X'
 Capturing subpattern count = 1
 Partial matching not supported
 No options
-First char at start or follows \n
+First char at start or follows newline
 No need char
 
 /(.*X|^B)/Ds
@@ -1221,7 +1215,7 @@ No need char
 Capturing subpattern count = 0
 Partial matching not supported
 No options
-First char at start or follows \n
+First char at start or follows newline
 No need char
 
 /\Biss\B/+
@@ -1306,7 +1300,7 @@ No need char
 Capturing subpattern count = 0
 Partial matching not supported
 No options
-First char at start or follows \n
+First char at start or follows newline
 Need char = 's'
     abciss\nxyzisspqr 
  0: abciss
@@ -1365,7 +1359,7 @@ No need char
 /^ab\n/mg+
 Capturing subpattern count = 0
 Options: multiline
-First char at start or follows \n
+First char at start or follows newline
 Need char = 10
     ab\nab\ncd
  0: ab\x0a
@@ -2223,7 +2217,6 @@ No need char
 /((?-i)[[:lower:]])[[:lower:]]/i
 Capturing subpattern count = 1
 Options: caseless
-Case state changes
 No first char
 No need char
     ab
@@ -2240,11 +2233,11 @@ No match
     AB        
 No match
 
-/[\200-\410]/
+/[\200-\110]/
 Failed: range out of order in character class at offset 9
 
 /^(?(0)f|b)oo/
-Failed: invalid condition (?(0) at offset 5
+Failed: invalid condition (?(0) at offset 6
 
 /This one's here because of the large output vector needed/
 Capturing subpattern count = 0
@@ -2761,7 +2754,6 @@ No need char
 ------------------------------------------------------------------
 Capturing subpattern count = 0
 No options
-Case state changes
 First char = 'a'
 Need char = 'b' (caseless)
     ab
@@ -2787,7 +2779,6 @@ No match
 ------------------------------------------------------------------
 Capturing subpattern count = 1
 No options
-Case state changes
 First char = 'a'
 Need char = 'b' (caseless)
     ab
@@ -3370,7 +3361,7 @@ No need char
 Capturing subpattern count = 1
 Partial matching not supported
 No options
-First char at start or follows \n
+First char at start or follows newline
 No need char
     
 /(.*)\d+\1/Is
@@ -3393,7 +3384,7 @@ Capturing subpattern count = 2
 Max back reference = 2
 Partial matching not supported
 No options
-First char at start or follows \n
+First char at start or follows newline
 Need char = 'z'
 
 /((.*))\d+\1/I
@@ -3430,7 +3421,6 @@ Need char = 'z' (caseless)
 /(?=abc)(?i).xyz/I
 Capturing subpattern count = 0
 No options
-Case state changes
 First char = 'a'
 Need char = 'z' (caseless)
 
@@ -3553,7 +3543,7 @@ Need char = 'b'
 /^a/mI
 Capturing subpattern count = 0
 Options: multiline
-First char at start or follows \n
+First char at start or follows newline
 Need char = 'a'
   abcde
  0: a
@@ -3580,7 +3570,6 @@ Starting byte set: A B a b
 /[ab](?i)cd/IS
 Capturing subpattern count = 0
 No options
-Case state changes
 No first char
 Need char = 'd' (caseless)
 Starting byte set: a b 
@@ -4503,12 +4492,12 @@ No first char
 Need char = 'z'
   aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\M
 Minimum match() limit = 8
-Minimum match() recursion limit = 7
+Minimum match() recursion limit = 6
  0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazz
  1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaz\M
 Minimum match() limit = 32768
-Minimum match() recursion limit = 43
+Minimum match() recursion limit = 42
 No match
 
 /(aaa(?C1)bbb|ab)/
@@ -4555,18 +4544,19 @@ Need char = 'h'
  1: cd
  2: gh
  1C cd (2)
- 2G gh (2)
+  G gh (2) two
     abcdefgh\Cone\Ctwo
  0: abcdefgh
  1: cd
  2: gh
- 1C cd (2)
- 2C gh (2)
+  C cd (2) one
+  C gh (2) two
     abcdefgh\Cthree  
 no parentheses with name "three"
  0: abcdefgh
  1: cd
  2: gh
+copy substring three failed -7
 
 /(?P<Tes>)(?P<Test>)/D
 ------------------------------------------------------------------
@@ -4616,18 +4606,18 @@ Need char = 'a'
  0: zzaa
  1: zz
  2: aa
- 1C zz (2)
+  C zz (2) Z
     zzaa\CA
  0: zzaa
  1: zz
  2: aa
- 2C aa (2)
+  C aa (2) A
 
 /(?P<x>eks)(?P<x>eccs)/
-Failed: two named groups have the same name at offset 16
+Failed: two named subpatterns have the same name at offset 16
 
 /(?P<abc>abc(?P<def>def)(?P<abc>xyz))/
-Failed: two named groups have the same name at offset 31
+Failed: two named subpatterns have the same name at offset 31
 
 "\[((?P<elem>\d+)(,(?P>elem))*)\]"
 Capturing subpattern count = 3
@@ -5769,7 +5759,6 @@ Failed: number too big in {} quantifier at offset 15
 Capturing subpattern count = 1
 Max back reference = 1
 No options
-Case state changes
 First char = 'a' (caseless)
 Need char = 'B'
     abcdefghijklAkB
@@ -6059,6 +6048,505 @@ No options
 First char = 255
 No need char
 
+/^((?P<A>a1)|(?P<A>a2)b)/
+Failed: two named subpatterns have the same name at offset 18
+
+/^((?P<A>a1)|(?P<A>a2)b)/J
+Capturing subpattern count = 3
+Named capturing subpatterns:
+  A   2
+  A   3
+Options: anchored dupnames
+No first char
+No need char
+    a1b\CA
+ 0: a1
+ 1: a1
+ 2: a1
+  C a1 (2) A
+    a2b\CA 
+ 0: a2b
+ 1: a2b
+ 2: <unset>
+ 3: a2
+  C a2 (2) A
+    ** Failers
+No match
+    a1b\CZ\CA 
+no parentheses with name "Z"
+ 0: a1
+ 1: a1
+ 2: a1
+copy substring Z failed -7
+  C a1 (2) A
+    
+/^(?P<A>a)(?P<A>b)/J
+Capturing subpattern count = 2
+Named capturing subpatterns:
+  A   1
+  A   2
+Options: anchored dupnames
+No first char
+No need char
+    ab\CA
+ 0: ab
+ 1: a
+ 2: b
+  C a (1) A
+    
+/^(?P<A>a)(?P<A>b)|cd/J
+Capturing subpattern count = 2
+Named capturing subpatterns:
+  A   1
+  A   2
+Options: dupnames
+No first char
+No need char
+    ab\CA
+ 0: ab
+ 1: a
+ 2: b
+  C a (1) A
+    cd\CA 
+ 0: cd
+copy substring A failed -7
+  
+/^(?P<A>a)(?P<A>b)|cd(?P<A>ef)(?P<A>gh)/J
+Capturing subpattern count = 4
+Named capturing subpatterns:
+  A   1
+  A   2
+  A   3
+  A   4
+Options: dupnames
+No first char
+No need char
+    cdefgh\CA 
+ 0: cdefgh
+ 1: <unset>
+ 2: <unset>
+ 3: ef
+ 4: gh
+  C ef (2) A
+  
+/^((?P<A>a1)|(?P<A>a2)b)/J
+Capturing subpattern count = 3
+Named capturing subpatterns:
+  A   2
+  A   3
+Options: anchored dupnames
+No first char
+No need char
+    a1b\GA
+ 0: a1
+ 1: a1
+ 2: a1
+  G a1 (2) A
+    a2b\GA 
+ 0: a2b
+ 1: a2b
+ 2: <unset>
+ 3: a2
+  G a2 (2) A
+    ** Failers
+No match
+    a1b\GZ\GA 
+no parentheses with name "Z"
+ 0: a1
+ 1: a1
+ 2: a1
+copy substring Z failed -7
+  G a1 (2) A
+    
+/^(?P<A>a)(?P<A>b)/J
+Capturing subpattern count = 2
+Named capturing subpatterns:
+  A   1
+  A   2
+Options: anchored dupnames
+No first char
+No need char
+    ab\GA
+ 0: ab
+ 1: a
+ 2: b
+  G a (1) A
+    
+/^(?P<A>a)(?P<A>b)|cd/J
+Capturing subpattern count = 2
+Named capturing subpatterns:
+  A   1
+  A   2
+Options: dupnames
+No first char
+No need char
+    ab\GA
+ 0: ab
+ 1: a
+ 2: b
+  G a (1) A
+    cd\GA 
+ 0: cd
+copy substring A failed -7
+  
+/^(?P<A>a)(?P<A>b)|cd(?P<A>ef)(?P<A>gh)/J
+Capturing subpattern count = 4
+Named capturing subpatterns:
+  A   1
+  A   2
+  A   3
+  A   4
+Options: dupnames
+No first char
+No need char
+    cdefgh\GA 
+ 0: cdefgh
+ 1: <unset>
+ 2: <unset>
+ 3: ef
+ 4: gh
+  G ef (2) A
+  
+/(?J)^((?P<A>a1)|(?P<A>a2)b)/
+Capturing subpattern count = 3
+Named capturing subpatterns:
+  A   2
+  A   3
+Options: anchored dupnames
+No first char
+No need char
+    a1b\CA
+ 0: a1
+ 1: a1
+ 2: a1
+  C a1 (2) A
+    a2b\CA 
+ 0: a2b
+ 1: a2b
+ 2: <unset>
+ 3: a2
+  C a2 (2) A
+    
+/^(?P<A>a) (?J:(?P<B>b)(?P<B>c)) (?P<A>d)/
+Failed: two named subpatterns have the same name at offset 38
+
+/ In this next test, J is not set at the outer level; consequently it isn't
+set in the pattern's options; consequently pcre_get_named_substring() produces 
+a random value. /x
+Capturing subpattern count = 1
+Options: extended
+First char = 'I'
+Need char = 'e'
+
+/^(?P<A>a) (?J:(?P<B>b)(?P<B>c)) (?P<C>d)/
+Capturing subpattern count = 4
+Named capturing subpatterns:
+  A   1
+  B   2
+  B   3
+  C   4
+Options: anchored
+No first char
+No need char
+    a bc d\CA\CB\CC
+ 0: a bc d
+ 1: a
+ 2: b
+ 3: c
+ 4: d
+  C a (1) A
+  C b (1) B
+  C d (1) C
+
+/^(?P<A>a)?(?(A)a|b)/
+Capturing subpattern count = 1
+Named capturing subpatterns:
+  A   1
+Options: anchored
+No first char
+No need char
+    aabc
+ 0: aa
+ 1: a
+    bc
+ 0: b
+    ** Failers
+No match
+    abc   
+No match
+
+/(?:(?(ZZ)a|b)(?P<ZZ>X))+/
+Capturing subpattern count = 1
+Named capturing subpatterns:
+  ZZ   1
+No options
+No first char
+Need char = 'X'
+    bXaX
+ 0: bXaX
+ 1: X
+
+/(?:(?(2y)a|b)(X))+/
+Failed: reference to non-existent subpattern at offset 9
+
+/(?:(?(ZA)a|b)(?P<ZZ>X))+/
+Failed: reference to non-existent subpattern at offset 9
+
+/(?:(?(ZZ)a|b)(?(ZZ)a|b)(?P<ZZ>X))+/
+Capturing subpattern count = 1
+Named capturing subpatterns:
+  ZZ   1
+No options
+No first char
+Need char = 'X'
+    bbXaaX
+ 0: bbXaaX
+ 1: X
+
+/(?:(?(ZZ)a|\(b\))\\(?P<ZZ>X))+/
+Capturing subpattern count = 1
+Named capturing subpatterns:
+  ZZ   1
+No options
+No first char
+Need char = 'X'
+    (b)\\Xa\\X
+ 0: (b)\Xa\X
+ 1: X
+
+/(?P<ABC/
+Failed: syntax error after (?P at offset 7
+
+/(?:(?(A)(?P=A)a|b)(?P<A>X|Y))+/
+Capturing subpattern count = 1
+Max back reference = 1
+Named capturing subpatterns:
+  A   1
+No options
+No first char
+No need char
+    bXXaYYaY
+ 0: bXXaYYaY
+ 1: Y
+    bXYaXXaX  
+ 0: bX
+ 1: X
+
+/()()()()()()()()()(?:(?(A)(?P=A)a|b)(?P<A>X|Y))+/
+Capturing subpattern count = 10
+Max back reference = 10
+Named capturing subpatterns:
+  A  10
+No options
+No first char
+No need char
+    bXXaYYaY
+ 0: bXXaYYaY
+ 1: 
+ 2: 
+ 3: 
+ 4: 
+ 5: 
+ 6: 
+ 7: 
+ 8: 
+ 9: 
+10: Y
+
+/\777/
+Failed: octal value is greater than \377 (not in UTF-8 mode) at offset 3
+
+/\s*,\s*/S
+Capturing subpattern count = 0
+Partial matching not supported
+No options
+No first char
+Need char = ','
+Starting byte set: \x09 \x0a \x0c \x0d \x20 , 
+    \x0b,\x0b
+ 0: ,
+    \x0c,\x0d 
+ 0: \x0c,\x0d
+
+/^abc/m
+Capturing subpattern count = 0
+Options: multiline
+First char at start or follows newline
+Need char = 'c'
+    xyz\nabc
+ 0: abc
+    xyz\nabc\<lf>
+ 0: abc
+    xyz\r\nabc\<lf>
+ 0: abc
+    xyz\rabc\<cr>
+ 0: abc
+    xyz\r\nabc\<crlf>
+ 0: abc
+    ** Failers 
+No match
+    xyz\nabc\<cr>
+No match
+    xyz\r\nabc\<cr>
+No match
+    xyz\nabc\<crlf>
+No match
+    xyz\rabc\<crlf>
+No match
+    xyz\rabc\<lf>
+No match
+    
+/abc$/m
+Capturing subpattern count = 0
+Options: multiline
+First char = 'a'
+Need char = 'c'
+    xyzabc
+ 0: abc
+    xyzabc\n 
+ 0: abc
+    xyzabc\npqr 
+ 0: abc
+    xyzabc\r\<cr> 
+ 0: abc
+    xyzabc\rpqr\<cr> 
+ 0: abc
+    xyzabc\r\n\<crlf> 
+ 0: abc
+    xyzabc\r\npqr\<crlf> 
+ 0: abc
+    ** Failers
+No match
+    xyzabc\r 
+No match
+    xyzabc\rpqr 
+No match
+    xyzabc\r\n 
+No match
+    xyzabc\r\npqr 
+No match
+    
+/^abc/m<cr>
+Capturing subpattern count = 0
+Options: multiline
+Forced newline sequence: CR
+First char at start or follows newline
+Need char = 'c'
+    xyz\rabcdef
+ 0: abc
+    xyz\nabcdef\<lf>
+ 0: abc
+    ** Failers  
+No match
+    xyz\nabcdef
+No match
+       
+/^abc/m<lf>
+Capturing subpattern count = 0
+Options: multiline
+Forced newline sequence: LF
+First char at start or follows newline
+Need char = 'c'
+    xyz\nabcdef
+ 0: abc
+    xyz\rabcdef\<cr>
+ 0: abc
+    ** Failers  
+No match
+    xyz\rabcdef
+No match
+       
+/^abc/m<crlf>
+Capturing subpattern count = 0
+Options: multiline
+Forced newline sequence: CRLF
+First char at start or follows newline
+Need char = 'c'
+    xyz\r\nabcdef
+ 0: abc
+    xyz\rabcdef\<cr>
+ 0: abc
+    ** Failers  
+No match
+    xyz\rabcdef
+No match
+    
+/^abc/m<bad>
+Unknown newline type at: <bad>
+
+
+/abc/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'c'
+    xyz\rabc\<bad>
+Unknown newline type at: <bad>
+    abc  
+ 0: abc
+       
+/.*/
+Capturing subpattern count = 0
+Partial matching not supported
+No options
+First char at start or follows newline
+No need char
+    abc\ndef
+ 0: abc
+    abc\rdef
+ 0: abc\x0ddef
+    abc\r\ndef
+ 0: abc\x0d
+    \<cr>abc\ndef
+ 0: abc\x0adef
+    \<cr>abc\rdef
+ 0: abc
+    \<cr>abc\r\ndef
+ 0: abc
+    \<crlf>abc\ndef
+ 0: abc\x0adef
+    \<crlf>abc\rdef
+ 0: abc\x0ddef
+    \<crlf>abc\r\ndef
+ 0: abc
+
+/\w+(.)(.)?def/s
+Capturing subpattern count = 2
+Partial matching not supported
+Options: dotall
+No first char
+Need char = 'f'
+    abc\ndef
+ 0: abc\x0adef
+ 1: \x0a
+    abc\rdef
+ 0: abc\x0ddef
+ 1: \x0d
+    abc\r\ndef
+ 0: abc\x0d\x0adef
+ 1: \x0d
+ 2: \x0a
+
++((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)+
+Capturing subpattern count = 1
+Partial matching not supported
+No options
+No first char
+No need char
+   /* this is a C style comment */\M
+Minimum match() limit = 120
+Minimum match() recursion limit = 6
+ 0: /* this is a C style comment */
+ 1: /* this is a C style comment */
+
+/(?P<B>25[0-5]|2[0-4]\d|[01]?\d?\d)(?:\.(?P>B)){3}/
+Capturing subpattern count = 1
+Named capturing subpatterns:
+  B   1
+No options
+No first char
+Need char = '.'
+
 / End of testinput2 /
 Capturing subpattern count = 0
 No options
index 1b98f86a304f478da07c1ae77e76078b3e9055ef..3b4945507531db945ed766eb207bb885950bd608 100644 (file)
@@ -898,8 +898,20 @@ No match
     \x{85}
  0: \x{85}
 
+/^ሴ/8
+    ሴ 
+ 0: \x{1234}
+
 /^\ሴ/8
     ሴ 
  0: \x{1234}
 
+"(?s)(.{1,5})"8
+    abcdefg
+ 0: abcde
+ 1: abcde
+    ab
+ 0: ab
+ 1: ab
+
 / End of testinput4 /
index 533fd84b657696211ee4f0f3a4e676768ef2aa82..2c5e3c09cd470746d94e4dded427c03c8961a80c 100644 (file)
@@ -1107,4 +1107,17 @@ Options: anchored utf8
 No first char
 No need char
 
+/\777/I
+Failed: octal value is greater than \377 (not in UTF-8 mode) at offset 3
+
+/\777/8I
+Capturing subpattern count = 0
+Options: utf8
+First char = 199
+Need char = 191
+  \x{1ff}
+ 0: \x{1ff}
+  \777 
+ 0: \x{1ff}
+
 / End of testinput5 /
index 87833bd263ad12d848b6f28235e1ea4ed713cab5..ee174a6b016d8f80af6e451f451ef24faeec5e56 100644 (file)
@@ -1394,4 +1394,20 @@ No match
      AXY      
 No match
 
+/^(\p{Z}[^\p{C}\p{Z}]+)*$/
+    \xa0!
+ 0: \xa0!
+ 1: \xa0!
+
+/^[\pL](abc)(?1)/
+    AabcabcYZ    
+ 0: Aabcabc
+ 1: abc
+
+/([\pL]=(abc))*X/
+    L=abcX
+ 0: L=abcX
+ 1: L=abc
+ 2: abc
+
 / End of testinput6 /
index 13e18bace689404839f689374b3495072a31d622..53d4e5a301287de585527db70ca031998c479513 100644 (file)
@@ -3004,13 +3004,13 @@ No match
     abc\xd3
  0: abc\xd3
 
-/(abc)\500/
+/(abc)\100/
     abc\x40
  0: abc@
     abc\100
  0: abc@
 
-/(abc)\5000/
+/(abc)\1000/
     abc\x400
  0: abc@0
     abc\x40\x30
@@ -6523,4 +6523,210 @@ Partial match: 123
     4\P\R
  0: 4
 
+/^/mg
+    a\nb\nc\n
+ 0: 
+ 0: 
+ 0: 
+    \ 
+ 0: 
+    
+/(?<=C\n)^/mg
+    A\nC\nC\n 
+ 0: 
+
+/(?s)A?B/
+    AB
+ 0: AB
+    aB  
+ 0: B
+
+/(?s)A*B/
+    AB
+ 0: AB
+    aB  
+ 0: B
+
+/(?m)A?B/
+    AB
+ 0: AB
+    aB  
+ 0: B
+
+/(?m)A*B/
+    AB
+ 0: AB
+    aB  
+ 0: B
+
+/Content-Type\x3A[^\r\n]{6,}/
+    Content-Type:xxxxxyyy 
+ 0: Content-Type:xxxxxyyy
+ 1: Content-Type:xxxxxyy
+ 2: Content-Type:xxxxxy
+
+/Content-Type\x3A[^\r\n]{6,}z/
+    Content-Type:xxxxxyyyz
+ 0: Content-Type:xxxxxyyyz
+
+/Content-Type\x3A[^a]{6,}/
+    Content-Type:xxxyyy 
+ 0: Content-Type:xxxyyy
+
+/Content-Type\x3A[^a]{6,}z/
+    Content-Type:xxxyyyz
+ 0: Content-Type:xxxyyyz
+
+/^abc/m
+    xyz\nabc
+ 0: abc
+    xyz\nabc\<lf>
+ 0: abc
+    xyz\r\nabc\<lf>
+ 0: abc
+    xyz\rabc\<cr>
+ 0: abc
+    xyz\r\nabc\<crlf>
+ 0: abc
+    ** Failers 
+No match
+    xyz\nabc\<cr>
+No match
+    xyz\r\nabc\<cr>
+No match
+    xyz\nabc\<crlf>
+No match
+    xyz\rabc\<crlf>
+No match
+    xyz\rabc\<lf>
+No match
+    
+/abc$/m
+    xyzabc
+ 0: abc
+    xyzabc\n 
+ 0: abc
+    xyzabc\npqr 
+ 0: abc
+    xyzabc\r\<cr> 
+ 0: abc
+    xyzabc\rpqr\<cr> 
+ 0: abc
+    xyzabc\r\n\<crlf> 
+ 0: abc
+    xyzabc\r\npqr\<crlf> 
+ 0: abc
+    ** Failers
+No match
+    xyzabc\r 
+No match
+    xyzabc\rpqr 
+No match
+    xyzabc\r\n 
+No match
+    xyzabc\r\npqr 
+No match
+    
+/^abc/m<cr>
+    xyz\rabcdef
+ 0: abc
+    xyz\nabcdef\<lf>
+ 0: abc
+    ** Failers  
+No match
+    xyz\nabcdef
+No match
+       
+/^abc/m<lf>
+    xyz\nabcdef
+ 0: abc
+    xyz\rabcdef\<cr>
+ 0: abc
+    ** Failers  
+No match
+    xyz\rabcdef
+No match
+       
+/^abc/m<crlf>
+    xyz\r\nabcdef
+ 0: abc
+    xyz\rabcdef\<cr>
+ 0: abc
+    ** Failers  
+No match
+    xyz\rabcdef
+No match
+    
+/.*/
+    abc\ndef
+ 0: abc
+ 1: ab
+ 2: a
+ 3: 
+    abc\rdef
+ 0: abc\x0ddef
+ 1: abc\x0dde
+ 2: abc\x0dd
+ 3: abc\x0d
+ 4: abc
+ 5: ab
+ 6: a
+ 7: 
+    abc\r\ndef
+ 0: abc\x0d
+ 1: abc
+ 2: ab
+ 3: a
+ 4: 
+    \<cr>abc\ndef
+ 0: abc\x0adef
+ 1: abc\x0ade
+ 2: abc\x0ad
+ 3: abc\x0a
+ 4: abc
+ 5: ab
+ 6: a
+ 7: 
+    \<cr>abc\rdef
+ 0: abc
+ 1: ab
+ 2: a
+ 3: 
+    \<cr>abc\r\ndef
+ 0: abc
+ 1: ab
+ 2: a
+ 3: 
+    \<crlf>abc\ndef
+ 0: abc\x0adef
+ 1: abc\x0ade
+ 2: abc\x0ad
+ 3: abc\x0a
+ 4: abc
+ 5: ab
+ 6: a
+ 7: 
+    \<crlf>abc\rdef
+ 0: abc\x0ddef
+ 1: abc\x0dde
+ 2: abc\x0dd
+ 3: abc\x0d
+ 4: abc
+ 5: ab
+ 6: a
+ 7: 
+    \<crlf>abc\r\ndef
+ 0: abc
+ 1: ab
+ 2: a
+ 3: 
+
+/\w+(.)(.)?def/s
+    abc\ndef
+ 0: abc\x0adef
+    abc\rdef
+ 0: abc\x0ddef
+    abc\r\ndef
+ 0: abc\x0d\x0adef
+
 / End of testinput7 /