------------------
+Version 3.2 12-May-00
+---------------------
+
+This is purely a bug fixing release.
+
+1. If the pattern /((Z)+|A)*/ was matched agained ZABCDEFG it matched Z instead
+of ZA. This was just one example of several cases that could provoke this bug,
+which was introduced by change 9 of version 2.00. The code for breaking
+infinite loops after an iteration that matches an empty string was't working
+correctly.
+
+2. The pcretest program was not imitating Perl correctly for the pattern /a*/g
+when matched against abbab (for example). After matching an empty string, it
+wasn't forcing anchoring when setting PCRE_NOTEMPTY for the next attempt; this
+caused it to match further down the string than it should.
+
+3. The code contained an inclusion of sys/types.h. It isn't clear why this
+was there because it doesn't seem to be needed, and it causes trouble on some
+systems, as it is not a Standard C header. It has been removed.
+
+4. Made 4 silly changes to the source to avoid stupid compiler warnings that
+were reported on the Macintosh. The changes were from
+
+ while ((c = *(++ptr)) != 0 && c != '\n');
+to
+ while ((c = *(++ptr)) != 0 && c != '\n') ;
+
+Totally extraordinary, but if that's what it takes...
+
+5. PCRE is being used in one environment where neither memmove() nor bcopy() is
+available. Added HAVE_BCOPY and an autoconf test for it; if neither
+HAVE_MEMMOVE nor HAVE_BCOPY is set, use a built-in emulation function which
+assumes the way PCRE uses memmove() (always moving upwards).
+
+6. PCRE is being used in one environment where strchr() is not available. There
+was only one use in pcre.c, and writing it out to avoid strchr() probably gives
+faster code anyway.
+
+
Version 3.1 09-Feb-00
---------------------
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
2. The origin of this software must not be misrepresented, either by
- explicit claim or by omission.
+ explicit claim or by omission. In practice, this means you must put
+ a sentence like this
+
+ Regular expression support is provided by the PCRE library package,
+ which is open source software, copyright by the University of
+ Cambridge.
+
+ somewhere reasonably visible in your documentation and in any relevant
+ files. A reference to the ftp site for the source should also be given
+
+ ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
+
+ in the documentation.
3. Altered versions must be plainly marked as such, and must not be
misrepresented as being the original software.
Return information about the first character of any matched string, for a
non-anchored pattern. If there is a fixed first character, e.g. from a pattern
-such as (cat|cow|coyote), then it is returned in the integer pointed to by
+such as (cat|cow|coyote), it is returned in the integer pointed to by
\fIwhere\fR. Otherwise, if either
(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch
(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set
(if it were set, the pattern would be anchored),
-then -1 is returned, indicating that the pattern matches only at the
-start of a subject string or after any "\\n" within the string. Otherwise -2 is
-returned. For anchored patterns, -2 is returned.
+-1 is returned, indicating that the pattern matches only at the start of a
+subject string or after any "\\n" within the string. Otherwise -2 is returned.
+For anchored patterns, -2 is returned.
PCRE_INFO_FIRSTTABLE
were captured by the match, including the substring that matched the entire
regular expression. This is the value returned by \fBpcre_exec\fR if it
is greater than zero. If \fBpcre_exec()\fR returned zero, indicating that it
-ran out of space in \fIovector\fR, then the value passed as
-\fIstringcount\fR should be the size of the vector divided by three.
+ran out of space in \fIovector\fR, the value passed as \fIstringcount\fR should
+be the size of the vector divided by three.
The functions \fBpcre_copy_substring()\fR and \fBpcre_get_substring()\fR
extract a single substring, whose number is given as \fIstringnumber\fR. A
with the settings of captured strings when part of a pattern is repeated. For
example, matching "aba" against the pattern /^(a(b)?)+$/ sets $2 to the value
"b", but matching "aabbaa" against /^(aa(bb)?)+$/ leaves $2 unset. However, if
-the pattern is changed to /^(aa(b(b))?)+$/ then $2 (and $3) get set.
+the pattern is changed to /^(aa(b(b))?)+$/ then $2 (and $3) are set.
In Perl 5.004 $2 is set in both cases, and that is also true of PCRE. If in the
future Perl changes to a consistent state that is different, PCRE may change to
.SH FULL STOP (PERIOD, DOT)
Outside a character class, a dot in the pattern matches any one character in
the subject, including a non-printing character, but not (by default) newline.
-If the PCRE_DOTALL option is set, then dots match newlines as well. The
-handling 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.
+If the PCRE_DOTALL option is set, dots match newlines as well. The handling 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.
.SH SQUARE BRACKETS
fails, because it matches the entire string due to the greediness of the .*
item.
-However, if a quantifier is followed by a question mark, then it ceases to be
+However, if a quantifier is followed by a question mark, it ceases to be
greedy, and instead matches the minimum number of times possible, so the
pattern
which matches one digit by preference, but can match two if that is the only
way the rest of the pattern matches.
-If the PCRE_UNGREEDY option is set (an option which is not available in Perl)
-then the quantifiers are not greedy by default, but individual ones can be made
+If the PCRE_UNGREEDY option is set (an option which is not available in Perl),
+the quantifiers are not greedy by default, but individual ones can be made
greedy by following them with a question mark. In other words, it inverts the
default behaviour.
compiled pattern, in proportion to the size of the minimum or maximum.
If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equivalent
-to Perl's /s) is set, thus allowing the . to match newlines, then the pattern
-is implicitly anchored, because whatever follows will be tried against every
+to Perl's /s) is set, thus allowing the . to match newlines, the pattern is
+implicitly anchored, because whatever follows will be tried against every
character position in the subject string, so there is no point in retrying the
overall match at any position after the first. PCRE treats such a pattern as
though it were preceded by \\A. In cases where it is known that the subject
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, then the case of letters is relevant. For example,
+back reference, the case of letters is relevant. For example,
((?i)rah)\\s+\\1
capturing subpattern is matched caselessly.
There may be more than one back reference to the same subpattern. If a
-subpattern has not actually been used in a particular match, then any back
+subpattern has not actually been used in a particular match, any back
references to it always fail. For example, the pattern
(a|(bc))\\2
always fails if it starts to match "a" rather than "bc". Because there may be
up to 99 back references, all digits following the backslash are taken
as part of a potential back reference number. If the pattern continues with a
-digit character, then some delimiter must be used to terminate the back
-reference. If the PCRE_EXTENDED option is set, this can be whitespace.
-Otherwise an empty comment can be used.
+digit character, some delimiter must be used to terminate the back reference.
+If the PCRE_EXTENDED option is set, this can be whitespace. Otherwise an empty
+comment can be used.
A back reference that occurs inside the parentheses to which it refers fails
when the subpattern is first used, so, for example, (a\\1) never matches.
matches "foo" preceded by three digits that are not "999". Notice that each of
the assertions is applied independently at the same point in the subject
string. First there is a check that the previous three characters are all
-digits, then there is a check that the same three characters are not "999".
+digits, and then there is a check that the same three characters are not "999".
This pattern does \fInot\fR match "foo" preceded by six characters, the first
of which are digits and the last three of which are not "999". For example, it
doesn't match "123abcfoo". A pattern to do that is
^.*abcd$
-then the initial .* matches the entire string at first, but when this fails
-(because there is no following "a"), it backtracks to match all but the last
-character, then all but the last two characters, and so on. Once again the
-search for "a" covers the entire string, from right to left, so we are no
-better off. However, if the pattern is written as
+the initial .* matches the entire string at first, but when this fails (because
+there is no following "a"), it backtracks to match all but the last character,
+then all but the last two characters, and so on. Once again the search for "a"
+covers the entire string, from right to left, so we are no better off. However,
+if the pattern is written as
^(?>.*)(?<=abcd)
-then there can be no backtracking for the .* item; it can match only the entire
+there can be no backtracking for the .* item; it can match only the entire
string. The subsequent lookbehind assertion does a single test on the last four
characters. If it fails, the match fails immediately. For long strings, this
approach makes a significant difference to the processing time.
subpattern, a compile-time error occurs.
There are two kinds of condition. If the text between the parentheses consists
-of a sequence of digits, then the condition is satisfied if the capturing
-subpattern of that number has previously matched. 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:
+of a sequence of digits, the condition is satisfied if the capturing subpattern
+of that number has previously matched. 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) \\) )
\\( ( ( (?>[^()]+) | (?R) )* ) \\)
^ ^
^ ^
-then the string they capture is "ab(cd)ef", the contents of the top level
+the string they capture is "ab(cd)ef", the contents of the top level
parentheses. If there are more than 15 capturing parentheses in a pattern, PCRE
has to obtain extra memory to store data during a recursion, which it does by
using \fBpcre_malloc\fR, freeing it via \fBpcre_free\fR afterwards. If no
<P>
Return information about the first character of any matched string, for a
non-anchored pattern. If there is a fixed first character, e.g. from a pattern
-such as (cat|cow|coyote), then it is returned in the integer pointed to by
+such as (cat|cow|coyote), it is returned in the integer pointed to by
<I>where</I>. Otherwise, if either
</P>
<P>
(if it were set, the pattern would be anchored),
</P>
<P>
-then -1 is returned, indicating that the pattern matches only at the
-start of a subject string or after any "\n" within the string. Otherwise -2 is
-returned. For anchored patterns, -2 is returned.
+-1 is returned, indicating that the pattern matches only at the start of a
+subject string or after any "\n" within the string. Otherwise -2 is returned.
+For anchored patterns, -2 is returned.
</P>
<P>
<PRE>
were captured by the match, including the substring that matched the entire
regular expression. This is the value returned by <B>pcre_exec</B> if it
is greater than zero. If <B>pcre_exec()</B> returned zero, indicating that it
-ran out of space in <I>ovector</I>, then the value passed as
-<I>stringcount</I> should be the size of the vector divided by three.
+ran out of space in <I>ovector</I>, the value passed as <I>stringcount</I> should
+be the size of the vector divided by three.
</P>
<P>
The functions <B>pcre_copy_substring()</B> and <B>pcre_get_substring()</B>
with the settings of captured strings when part of a pattern is repeated. For
example, matching "aba" against the pattern /^(a(b)?)+$/ sets $2 to the value
"b", but matching "aabbaa" against /^(aa(bb)?)+$/ leaves $2 unset. However, if
-the pattern is changed to /^(aa(b(b))?)+$/ then $2 (and $3) get set.
+the pattern is changed to /^(aa(b(b))?)+$/ then $2 (and $3) are set.
</P>
<P>
In Perl 5.004 $2 is set in both cases, and that is also true of PCRE. If in the
<P>
Outside a character class, a dot in the pattern matches any one character in
the subject, including a non-printing character, but not (by default) newline.
-If the PCRE_DOTALL option is set, then dots match newlines as well. The
-handling 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.
+If the PCRE_DOTALL option is set, dots match newlines as well. The handling 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.
</P>
<LI><A NAME="SEC17" HREF="#TOC1">SQUARE BRACKETS</A>
<P>
item.
</P>
<P>
-However, if a quantifier is followed by a question mark, then it ceases to be
+However, if a quantifier is followed by a question mark, it ceases to be
greedy, and instead matches the minimum number of times possible, so the
pattern
</P>
way the rest of the pattern matches.
</P>
<P>
-If the PCRE_UNGREEDY option is set (an option which is not available in Perl)
-then the quantifiers are not greedy by default, but individual ones can be made
+If the PCRE_UNGREEDY option is set (an option which is not available in Perl),
+the quantifiers are not greedy by default, but individual ones can be made
greedy by following them with a question mark. In other words, it inverts the
default behaviour.
</P>
</P>
<P>
If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equivalent
-to Perl's /s) is set, thus allowing the . to match newlines, then the pattern
-is implicitly anchored, because whatever follows will be tried against every
+to Perl's /s) is set, thus allowing the . to match newlines, the pattern is
+implicitly anchored, because whatever follows will be tried against every
character position in the subject string, so there is no point in retrying the
overall match at any position after the first. PCRE treats such a pattern as
though it were preceded by \A. In cases where it is known that the subject
<P>
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, then the case of letters is relevant. For example,
+back reference, the case of letters is relevant. For example,
</P>
<P>
<PRE>
</P>
<P>
There may be more than one back reference to the same subpattern. If a
-subpattern has not actually been used in a particular match, then any back
+subpattern has not actually been used in a particular match, any back
references to it always fail. For example, the pattern
</P>
<P>
always fails if it starts to match "a" rather than "bc". Because there may be
up to 99 back references, all digits following the backslash are taken
as part of a potential back reference number. If the pattern continues with a
-digit character, then some delimiter must be used to terminate the back
-reference. If the PCRE_EXTENDED option is set, this can be whitespace.
-Otherwise an empty comment can be used.
+digit character, some delimiter must be used to terminate the back reference.
+If the PCRE_EXTENDED option is set, this can be whitespace. Otherwise an empty
+comment can be used.
</P>
<P>
A back reference that occurs inside the parentheses to which it refers fails
matches "foo" preceded by three digits that are not "999". Notice that each of
the assertions is applied independently at the same point in the subject
string. First there is a check that the previous three characters are all
-digits, then there is a check that the same three characters are not "999".
+digits, and then there is a check that the same three characters are not "999".
This pattern does <I>not</I> match "foo" preceded by six characters, the first
of which are digits and the last three of which are not "999". For example, it
doesn't match "123abcfoo". A pattern to do that is
</PRE>
</P>
<P>
-then the initial .* matches the entire string at first, but when this fails
-(because there is no following "a"), it backtracks to match all but the last
-character, then all but the last two characters, and so on. Once again the
-search for "a" covers the entire string, from right to left, so we are no
-better off. However, if the pattern is written as
+the initial .* matches the entire string at first, but when this fails (because
+there is no following "a"), it backtracks to match all but the last character,
+then all but the last two characters, and so on. Once again the search for "a"
+covers the entire string, from right to left, so we are no better off. However,
+if the pattern is written as
</P>
<P>
<PRE>
</PRE>
</P>
<P>
-then there can be no backtracking for the .* item; it can match only the entire
+there can be no backtracking for the .* item; it can match only the entire
string. The subsequent lookbehind assertion does a single test on the last four
characters. If it fails, the match fails immediately. For long strings, this
approach makes a significant difference to the processing time.
</P>
<P>
There are two kinds of condition. If the text between the parentheses consists
-of a sequence of digits, then the condition is satisfied if the capturing
-subpattern of that number has previously matched. 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:
+of a sequence of digits, the condition is satisfied if the capturing subpattern
+of that number has previously matched. 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:
</P>
<P>
<PRE>
^ ^
^ ^
</PRE>
-then the string they capture is "ab(cd)ef", the contents of the top level
+the string they capture is "ab(cd)ef", the contents of the top level
parentheses. If there are more than 15 capturing parentheses in a pattern, PCRE
has to obtain extra memory to store data during a recursion, which it does by
using <B>pcre_malloc</B>, freeing it via <B>pcre_free</B> afterwards. If no
Return information about the first character of any matched
string, for a non-anchored pattern. If there is a fixed
first character, e.g. from a pattern such as
- (cat|cow|coyote), then it is returned in the integer pointed
- to by where. Otherwise, if either
+ (cat|cow|coyote), it is returned in the integer pointed to
+ by where. Otherwise, if either
(a) the pattern was compiled with the PCRE_MULTILINE option,
and every branch starts with "^", or
PCRE_DOTALL is not set (if it were set, the pattern would be
anchored),
- then -1 is returned, indicating that the pattern matches
- only at the start of a subject string or after any "\n"
- within the string. Otherwise -2 is returned. For anchored
- patterns, -2 is returned.
+ -1 is returned, indicating that the pattern matches only at
+ the start of a subject string or after any "\n" within the
+ string. Otherwise -2 is returned. For anchored patterns, -2
+ is returned.
PCRE_INFO_FIRSTTABLE
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 ovec-
- tor, then the value passed as stringcount should be the size
- of the vector divided by three.
+ tor, the value passed as stringcount should be the size of
+ the vector divided by three.
The functions pcre_copy_substring() and pcre_get_substring()
extract a single substring, whose number is given as string-
"aba" against the pattern /^(a(b)?)+$/ sets $2 to the value
"b", but matching "aabbaa" against /^(aa(bb)?)+$/ leaves $2
unset. However, if the pattern is changed to
- /^(aa(b(b))?)+$/ then $2 (and $3) get set.
+ /^(aa(b(b))?)+$/ then $2 (and $3) are set.
In Perl 5.004 $2 is set in both cases, and that is also true
of PCRE. If in the future Perl changes to a consistent state
Outside a character class, a dot in the pattern matches any
one character in the subject, including a non-printing char-
acter, but not (by default) newline. If the PCRE_DOTALL
- option is set, then dots match newlines as well. The han-
- dling of dot is entirely independent of the handling of cir-
- cumflex and dollar, the only relationship being that they
- both involve newline characters. Dot has no special meaning
- in a character class.
+ option is set, dots match newlines as well. The handling 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.
fails, because it matches the entire string due to the
greediness of the .* item.
- However, if a quantifier is followed by a question mark,
- then it ceases to be greedy, and instead matches the minimum
- number of times possible, so the pattern
+ However, if a quantifier is followed by a question mark, it
+ ceases to be greedy, and instead matches the minimum number
+ of times possible, so the pattern
/\*.*?\*/
that is the only way the rest of the pattern matches.
If the PCRE_UNGREEDY option is set (an option which is not
- available in Perl) then the quantifiers are not greedy by
+ available in Perl), the quantifiers are not greedy by
default, but individual ones can be made greedy by following
them with a question mark. In other words, it inverts the
default behaviour.
If a pattern starts with .* or .{0,} and the PCRE_DOTALL
option (equivalent to Perl's /s) is set, thus allowing the .
- to match newlines, then the pattern is implicitly anchored,
+ to match newlines, the pattern is implicitly anchored,
because whatever follows will be tried against every charac-
ter position in the subject string, so there is no point in
retrying the overall match at any position after the first.
matches "sense and sensibility" and "response and responsi-
bility", but not "sense and responsibility". If caseful
- matching is in force at the time of the back reference, then
- the case of letters is relevant. For example,
+ matching is in force at the time of the back reference, the
+ case of letters is relevant. For example,
((?i)rah)\s+\1
There may be more than one back reference to the same sub-
pattern. If a subpattern has not actually been used in a
- particular match, then any back references to it always
- fail. For example, the pattern
+ particular match, any back references to it always fail. For
+ example, the pattern
(a|(bc))\2
Because there may be up to 99 back references, all digits
following the backslash are taken as part of a potential
back reference number. If the pattern continues with a digit
- character, then some delimiter must be used to terminate the
- back reference. If the PCRE_EXTENDED option is set, this can
- be whitespace. Otherwise an empty comment can be used.
+ character, some delimiter must be used to terminate the back
+ reference. If the PCRE_EXTENDED option is set, this can be
+ whitespace. Otherwise an empty comment can be used.
A back reference that occurs inside the parentheses to which
it refers fails when the subpattern is first used, so, for
matches "foo" preceded by three digits that are not "999".
Notice that each of the assertions is applied independently
at the same point in the subject string. First there is a
- check that the previous three characters are all digits,
+ check that the previous three characters are all digits, and
then there is a check that the same three characters are not
"999". This pattern does not match "foo" preceded by six
characters, the first of which are digits and the last three
^.*abcd$
- then the initial .* matches the entire string at first, but
- when this fails (because there is no following "a"), it
- backtracks to match all but the last character, then all but
- the last two characters, and so on. Once again the search
- for "a" covers the entire string, from right to left, so we
- are no better off. However, if the pattern is written as
+ the initial .* matches the entire string at first, but when
+ this fails (because there is no following "a"), it back-
+ tracks to match all but the last character, then all but the
+ last two characters, and so on. Once again the search for
+ "a" covers the entire string, from right to left, so we are
+ no better off. However, if the pattern is written as
^(?>.*)(?<=abcd)
- then there can be no backtracking for the .* item; it can
- match only the entire string. The subsequent lookbehind
- assertion does a single test on the last four characters. If
- it fails, the match fails immediately. For long strings,
- this approach makes a significant difference to the process-
- ing time.
+ there can be no backtracking for the .* item; it can match
+ only the entire string. The subsequent lookbehind assertion
+ does a single test on the last four characters. If it fails,
+ the match fails immediately. For long strings, this approach
+ makes a significant difference to the processing time.
When a pattern contains an unlimited repeat inside a subpat-
tern that can itself be repeated an unlimited number of
error occurs.
There are two kinds of condition. If the text between the
- parentheses consists of a sequence of digits, then the
- condition is satisfied if the capturing subpattern of that
- number has previously matched. Consider the following pat-
- tern, 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:
+ parentheses consists of a sequence of digits, the condition
+ is satisfied if the capturing subpattern of that number has
+ previously matched. Consider the following pattern, which
+ contains non-significant white space to make it more read-
+ able (assume the PCRE_EXTENDED option) and to divide it into
+ three parts for ease of discussion:
( \( )? [^()]+ (?(1) \) )
\( ( ( (?>[^()]+) | (?R) )* ) \)
^ ^
- ^ ^ then the string they capture
- is "ab(cd)ef", the contents of the top level parentheses. If
+ ^ ^ the string they capture is
+ "ab(cd)ef", the contents of the top level parentheses. If
there are more than 15 capturing parentheses in a pattern,
PCRE has to obtain extra memory to store data during a
recursion, which it does by using pcre_malloc, freeing it
(including \b or \B).
If any call to pcre_exec() in a /g or /G sequence matches an empty string, the
-next call is done with the PCRE_NOTEMPTY flag set so that it cannot match an
-empty string again at the same point. If however, this second match fails, the
-start offset is advanced by one, and the match is retried. This imitates the
-way Perl handles such cases when using the /g modifier or the split() function.
+next call is done with the PCRE_NOTEMPTY and PCRE_ANCHORED flags set in order
+to search for another, non-empty, match at the same point. If this second match
+fails, the start offset is advanced by one, and the normal match is retried.
+This imitates the way Perl handles such cases when using the /g modifier or the
+split() function.
There are a number of other modifiers for controlling the way pcretest
operates.
#endif
/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
-define a macro for memmove() if HAVE_MEMMOVE is false. */
+define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
+is set. Otherwise, include an emulating function for those systems that have
+neither (there some non-Unix environments where this is the case). This assumes
+that all calls to memmove are moving strings upwards in store, which is the
+case in PCRE. */
#if ! HAVE_MEMMOVE
#undef memmove /* some systems may have a macro */
+#if HAVE_BCOPY
#define memmove(a, b, c) bcopy(b, a, c)
+#else
+void *
+pcre_memmove(unsigned char *dest, const unsigned char *src, size_t n)
+{
+int i;
+dest += n;
+src += n;
+for (i = 0; i < n; ++i) *(--dest) = *(--src);
+}
+#define memmove(a, b, c) pcre_memmove(a, b, c)
+#endif
#endif
/* Standard C headers plus the external interface definition */
compile_regex(int, int, int *, uschar **, const uschar **, const char **,
BOOL, int, int *, int *, compile_data *);
+/* Structure for building a chain of data that actually lives on the
+stack, for holding the values of the subject pointer at the start of each
+subpattern, so as to detect when an empty string has been matched by a
+subpattern - to break infinite loops. */
+
+typedef struct eptrblock {
+ struct eptrblock *prev;
+ const uschar *saved_eptr;
+} eptrblock;
+
+/* Flag bits for the match() function */
+
+#define match_condassert 0x01 /* Called to check a condition assertion */
+#define match_isgroup 0x02 /* Set if start of bracketed group */
+
/*************************************************
if ((cd->ctypes[c] & ctype_space) != 0) continue;
if (c == '#')
{
- while ((c = *(++ptr)) != 0 && c != '\n');
+ /* The space before the ; is to avoid a warning on a silly compiler
+ on the Macintosh. */
+ while ((c = *(++ptr)) != 0 && c != '\n') ;
continue;
}
}
if ((cd->ctypes[c] & ctype_space) != 0) continue;
if (c == '#')
{
- while ((c = *(++ptr)) != 0 && c != '\n');
+ /* The space before the ; is to avoid a warning on a silly compiler
+ on the Macintosh. */
+ while ((c = *(++ptr)) != 0 && c != '\n') ;
if (c == 0) break;
continue;
}
if ((compile_block.ctypes[c] & ctype_space) != 0) continue;
if (c == '#')
{
- while ((c = *(++ptr)) != 0 && c != '\n');
+ /* The space before the ; is to avoid a warning on a silly compiler
+ on the Macintosh. */
+ while ((c = *(++ptr)) != 0 && c != '\n') ;
continue;
}
}
else /* An assertion must follow */
{
ptr++; /* Can treat like ':' as far as spacing is concerned */
-
- if (ptr[2] != '?' || strchr("=!<", ptr[3]) == NULL)
+ if (ptr[2] != '?' ||
+ (ptr[3] != '=' && ptr[3] != '!' && ptr[3] != '<') )
{
ptr += 2; /* To get right offset in message */
*errorptr = ERR28;
if ((compile_block.ctypes[c] & ctype_space) != 0) continue;
if (c == '#')
{
- while ((c = *(++ptr)) != 0 && c != '\n');
+ /* The space before the ; is to avoid a warning on a silly compiler
+ on the Macintosh. */
+ while ((c = *(++ptr)) != 0 && c != '\n') ;
continue;
}
}
offset_top current top pointer
md pointer to "static" info for the match
ims current /i, /m, and /s options
- condassert TRUE if called to check a condition assertion
- eptrb eptr at start of last bracket
+ eptrb pointer to chain of blocks containing eptr at start of
+ brackets - for testing for empty matches
+ flags can contain
+ match_condassert - this is an assertion condition
+ match_isgroup - this is the start of a bracketed group
Returns: TRUE if matched
*/
static BOOL
match(register const uschar *eptr, register const uschar *ecode,
- int offset_top, match_data *md, unsigned long int ims, BOOL condassert,
- const uschar *eptrb)
+ int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,
+ int flags)
{
unsigned long int original_ims = ims; /* Save for resetting on ')' */
+eptrblock newptrb;
+
+/* 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
+the closing ket. When match() is called in other circumstances, we don't add to
+the stack. */
+
+if ((flags & match_isgroup) != 0)
+ {
+ newptrb.prev = eptrb;
+ newptrb.saved_eptr = eptr;
+ eptrb = &newptrb;
+ }
+
+/* Now start processing the operations. */
for (;;)
{
do
{
- if (match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr)) return TRUE;
+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, match_isgroup))
+ return TRUE;
ecode += (ecode[1] << 8) + ecode[2];
}
while (*ecode == OP_ALT);
DPRINTF(("start bracket 0\n"));
do
{
- if (match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr)) return TRUE;
+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, match_isgroup))
+ return TRUE;
ecode += (ecode[1] << 8) + ecode[2];
}
while (*ecode == OP_ALT);
return match(eptr,
ecode + ((offset < offset_top && md->offset_vector[offset] >= 0)?
5 : 3 + (ecode[1] << 8) + ecode[2]),
- offset_top, md, ims, FALSE, eptr);
+ offset_top, md, ims, eptrb, match_isgroup);
}
/* The condition is an assertion. Call match() to evaluate it - setting
else
{
- if (match(eptr, ecode+3, offset_top, md, ims, TRUE, NULL))
+ if (match(eptr, ecode+3, offset_top, md, ims, NULL,
+ match_condassert | match_isgroup))
{
ecode += 3 + (ecode[4] << 8) + ecode[5];
while (*ecode == OP_ALT) ecode += (ecode[1] << 8) + ecode[2];
}
else ecode += (ecode[1] << 8) + ecode[2];
- return match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr);
+ return match(eptr, ecode+3, offset_top, md, ims, eptrb, match_isgroup);
}
/* Control never reaches here */
case OP_ASSERTBACK:
do
{
- if (match(eptr, ecode+3, offset_top, md, ims, FALSE, NULL)) break;
+ if (match(eptr, ecode+3, offset_top, md, ims, NULL, match_isgroup)) break;
ecode += (ecode[1] << 8) + ecode[2];
}
while (*ecode == OP_ALT);
/* If checking an assertion for a condition, return TRUE. */
- if (condassert) return TRUE;
+ if ((flags & match_condassert) != 0) return TRUE;
/* Continue from after the assertion, updating the offsets high water
mark, since extracts may have been taken during the assertion. */
case OP_ASSERTBACK_NOT:
do
{
- if (match(eptr, ecode+3, offset_top, md, ims, FALSE, NULL)) return FALSE;
+ if (match(eptr, ecode+3, offset_top, md, ims, NULL, match_isgroup))
+ return FALSE;
ecode += (ecode[1] << 8) + ecode[2];
}
while (*ecode == OP_ALT);
- if (condassert) return TRUE;
+ if ((flags & match_condassert) != 0) return TRUE;
+
ecode += 3;
continue;
for (i = 1; i <= c; i++)
save[i] = md->offset_vector[md->offset_end - i];
- rc = match(eptr, md->start_pattern, offset_top, md, ims, FALSE, eptrb);
+ rc = match(eptr, md->start_pattern, offset_top, md, ims, eptrb,
+ match_isgroup);
for (i = 1; i <= c; i++)
md->offset_vector[md->offset_end - i] = save[i];
if (save != stacksave) (pcre_free)(save);
case OP_ONCE:
{
const uschar *prev = ecode;
+ const uschar *saved_eptr = eptr;
do
{
- if (match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr)) break;
+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, match_isgroup))
+ break;
ecode += (ecode[1] << 8) + ecode[2];
}
while (*ecode == OP_ALT);
5.005. If there is an options reset, it will get obeyed in the normal
course of events. */
- if (*ecode == OP_KET || eptr == eptrb)
+ if (*ecode == OP_KET || eptr == saved_eptr)
{
ecode += 3;
break;
if (*ecode == OP_KETRMIN)
{
- if (match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr) ||
- match(eptr, prev, offset_top, md, ims, FALSE, eptr)) return TRUE;
+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, 0) ||
+ match(eptr, prev, offset_top, md, ims, eptrb, match_isgroup))
+ return TRUE;
}
else /* OP_KETRMAX */
{
- if (match(eptr, prev, offset_top, md, ims, FALSE, eptr) ||
- match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr)) return TRUE;
+ if (match(eptr, prev, offset_top, md, ims, eptrb, match_isgroup) ||
+ match(eptr, ecode+3, offset_top, md, ims, eptrb, 0)) return TRUE;
}
}
return FALSE;
case OP_BRAZERO:
{
const uschar *next = ecode+1;
- if (match(eptr, next, offset_top, md, ims, FALSE, eptr)) return TRUE;
+ if (match(eptr, next, offset_top, md, ims, eptrb, match_isgroup))
+ return TRUE;
do next += (next[1] << 8) + next[2]; while (*next == OP_ALT);
ecode = next + 3;
}
{
const uschar *next = ecode+1;
do next += (next[1] << 8) + next[2]; while (*next == OP_ALT);
- if (match(eptr, next+3, offset_top, md, ims, FALSE, eptr)) return TRUE;
+ if (match(eptr, next+3, offset_top, md, ims, eptrb, match_isgroup))
+ return TRUE;
ecode++;
}
break;
case OP_KETRMAX:
{
const uschar *prev = ecode - (ecode[1] << 8) - ecode[2];
+ const uschar *saved_eptr = eptrb->saved_eptr;
+
+ eptrb = eptrb->prev; /* Back up the stack of bracket start pointers */
if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
*prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
int number = *prev - OP_BRA;
int offset = number << 1;
- DPRINTF(("end bracket %d\n", number));
+#ifdef DEBUG
+ printf("end bracket %d", number);
+ printf("\n");
+#endif
if (number > 0)
{
5.005. If there is an options reset, it will get obeyed in the normal
course of events. */
- if (*ecode == OP_KET || eptr == eptrb)
+ if (*ecode == OP_KET || eptr == saved_eptr)
{
ecode += 3;
break;
if (*ecode == OP_KETRMIN)
{
- if (match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr) ||
- match(eptr, prev, offset_top, md, ims, FALSE, eptr)) return TRUE;
+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, 0) ||
+ match(eptr, prev, offset_top, md, ims, eptrb, match_isgroup))
+ return TRUE;
}
else /* OP_KETRMAX */
{
- if (match(eptr, prev, offset_top, md, ims, FALSE, eptr) ||
- match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr)) return TRUE;
+ if (match(eptr, prev, offset_top, md, ims, eptrb, match_isgroup) ||
+ match(eptr, ecode+3, offset_top, md, ims, eptrb, 0)) return TRUE;
}
}
return FALSE;
{
for (i = min;; i++)
{
- if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
if (i >= max || !match_ref(offset, eptr, length, md, ims))
return FALSE;
}
while (eptr >= pp)
{
- if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
eptr -= length;
}
{
for (i = min;; i++)
{
- if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
if (i >= max || eptr >= md->end_subject) return FALSE;
c = *eptr++;
}
while (eptr >= pp)
- if (match(eptr--, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
return FALSE;
}
{
for (i = min;; i++)
{
- if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
if (i >= max || eptr >= md->end_subject ||
c != md->lcc[*eptr++])
eptr++;
}
while (eptr >= pp)
- if (match(eptr--, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
return FALSE;
}
{
for (i = min;; i++)
{
- if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
if (i >= max || eptr >= md->end_subject || c != *eptr++) return FALSE;
}
eptr++;
}
while (eptr >= pp)
- if (match(eptr--, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
return FALSE;
}
{
for (i = min;; i++)
{
- if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
if (i >= max || eptr >= md->end_subject ||
c == md->lcc[*eptr++])
eptr++;
}
while (eptr >= pp)
- if (match(eptr--, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
return FALSE;
}
{
for (i = min;; i++)
{
- if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
if (i >= max || eptr >= md->end_subject || c == *eptr++) return FALSE;
}
eptr++;
}
while (eptr >= pp)
- if (match(eptr--, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
return FALSE;
}
{
for (i = min;; i++)
{
- if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb)) return TRUE;
+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0)) return TRUE;
if (i >= max || eptr >= md->end_subject) return FALSE;
c = *eptr++;
}
while (eptr >= pp)
- if (match(eptr--, ecode, offset_top, md, ims, FALSE, eptrb))
+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0))
return TRUE;
return FALSE;
}
if certain parts of the pattern were not used. */
match_block.start_match = start_match;
- if (!match(start_match, re->code, 2, &match_block, ims, FALSE, start_match))
+ if (!match(start_match, re->code, 2, &match_block, ims, NULL, match_isgroup))
continue;
/* Copy the offset information from temporary store if necessary */
}
/* Failed to match. If this is a /g or /G loop and we previously set
- PCRE_NOTEMPTY after a null match, this is not necessarily the end.
+ g_notempty after a null match, this is not necessarily the end.
We want to advance the start offset, and continue. Fudge the offset
values to achieve this. We won't be at the end of the string - that
- was checked before setting PCRE_NOTEMPTY. */
+ was checked before setting g_notempty. */
else
{
/* If we have matched an empty string, first check to see if we are at
the end of the subject. If so, the /g loop is over. Otherwise, mimic
what Perl's /g options does. This turns out to be rather cunning. First
- we set PCRE_NOTEMPTY and try the match again at the same point. If this
- fails (picked up above) we advance to the next character. */
+ we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the
+ same point. If this fails (picked up above) we advance to the next
+ character. */
g_notempty = 0;
if (offsets[0] == offsets[1])
{
if (offsets[0] == len) break;
- g_notempty = PCRE_NOTEMPTY;
+ g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED;
}
/* For /g, update the start offset, leaving the rest alone */
<a href=\"abcd xyz pqr\" cats
<a href = \'abcd xyz pqr\' cats
+/((Z)+|A)*/
+ ZABCDEFG
+
+/(Z()|A)*/
+ ZABCDEFG
+
+/(Z(())|A)*/
+ ZABCDEFG
+
+/((?>Z)+|A)*/
+ ZABCDEFG
+
+/((?>)+|A)*/
+ ZABCDEFG
+
+/a*/g
+ abbab
+
/ End of test input /
-PCRE version 3.1 09-Feb-2000
+PCRE version 3.2 12-May-2000
/the quick brown fox/
the quick brown fox
-PCRE version 3.1 09-Feb-2000
+PCRE version 3.2 12-May-2000
/(a)b|/
Capturing subpattern count = 1
-PCRE version 3.1 09-Feb-2000
+PCRE version 3.2 12-May-2000
/(?<!bar)foo/
foo
1: '
2: abcd xyz pqr
+/((Z)+|A)*/
+ ZABCDEFG
+ 0: ZA
+ 1: A
+ 2: Z
+
+/(Z()|A)*/
+ ZABCDEFG
+ 0: ZA
+ 1: A
+ 2:
+
+/(Z(())|A)*/
+ ZABCDEFG
+ 0: ZA
+ 1: A
+ 2:
+ 3:
+
+/((?>Z)+|A)*/
+ ZABCDEFG
+ 0: ZA
+ 1: A
+
+/((?>)+|A)*/
+ ZABCDEFG
+ 0:
+ 1:
+
+/a*/g
+ abbab
+ 0: a
+ 0:
+ 0:
+ 0: a
+ 0:
+ 0:
+
/ End of test input /
-PCRE version 3.1 09-Feb-2000
+PCRE version 3.2 12-May-2000
/^[\w]+/
*** Failers
This turns out to be rather cunning. First we set PCRE_NOTEMPTY and try
the match again at the same point. If this fails (picked up above) we
advance to the next character. */
- g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY : 0;
+ g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY | PCRE_ANCHORED : 0;
/* Advance to the position right after the last full match */
start_offset = offsets[1];
This turns out to be rather cunning. First we set PCRE_NOTEMPTY and try
the match again at the same point. If this fails (picked up above) we
advance to the next character. */
- g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY : 0;
+ g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY | PCRE_ANCHORED : 0;
/* Advance to the next piece */
start_offset = offsets[1];
*subject_value,
*result;
int subject_len,
- replace_len;
+ replace_len = 0;
/* Make sure we're dealing with strings. */
convert_to_string_ex(subject);
This turns out to be rather cunning. First we set PCRE_NOTEMPTY and try
the match again at the same point. If this fails (picked up above) we
advance to the next character. */
- g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY : 0;
+ g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY | PCRE_ANCHORED : 0;
/* Advance to the position right after the last full match */
start_offset = offsets[1];
break;
default:
- if (c == delim_char && quote_delim)
+ if (quote_delim && c == delim_char)
*q++ = '\\';
*q++ = c;
break;